😎 κ³΅λΆ€ν•˜λŠ” μ§•μ§•μ•ŒνŒŒμΉ΄λŠ” μ²˜μŒμ΄μ§€?

[λ¦¬λˆ…μŠ€ λ„€νŠΈμ›Œν¬ ν”„λ‘œκ·Έλž˜λ°] TCPμ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ ν”„λ‘œκ·Έλž˜λ° λ³Έλ¬Έ

πŸ‘©‍πŸ’» IoT (Embedded)/Raspberry Pi

[λ¦¬λˆ…μŠ€ λ„€νŠΈμ›Œν¬ ν”„λ‘œκ·Έλž˜λ°] TCPμ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ ν”„λ‘œκ·Έλž˜λ°

μ§•μ§•μ•ŒνŒŒμΉ΄ 2024. 1. 31. 12:37
728x90
λ°˜μ‘ν˜•

<μ„œμ˜μ§„ λ‹˜μ˜ 사물인터넷을 μœ„ν•œ λ¦¬λˆ…μŠ€ ν”„λ‘œκ·Έλž˜λ° with λΌμ¦ˆλ² λ¦¬νŒŒμ΄ μ„œμ μ„ μ°Έκ³ ν•΄μ„œ μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€ :-)>

 

⭐ TCP 

TCP λŠ” μ—°κ²° 기반의 신뒰성이 μžˆλŠ” 톡신 λ°©μ‹μœΌλ‘œ FTP, 메일, μ›Ή μ„œλΉ„μŠ€ λ“± 인터넷을 μ΄μš©ν•œ λ‹€μ–‘ν•œ μ„œλΉ„μŠ€μ—μ„œ μ‚¬μš©λ˜κ³  μžˆλ‹€

TCP λŠ” 주둜 μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ κ°„ 톡신 방식이닀

 

TCP μ„œλ²„λŠ” μ†ŒμΌ“μ„ μƒμ„±ν•œ ν›„ λ°”μΈλ“œ (bind) ν•˜λŠ” 과정은 UDP κ³Όμ •κ³Ό λ™μΌν•˜λ‹€

but🚨 UDP와 λ‹€λ₯΄κ²Œ TCP λŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ 3 Way-Handshaking (connect() ν•¨μˆ˜) λ₯Ό ν†΅ν•΄μ„œ μ„œλ²„μ— μ ‘μ†ν•˜κΈ° λ•Œλ¬Έμ— ν΄λΌμ΄μ–ΈνŠΈμ˜ λŒ€κΈ°λ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ 큐 (queue) κ°€ ν•„μš”ν•˜λ‹€

이λ₯Ό μœ„ν•΄ listen() ν•¨μˆ˜λ₯Ό 톡해 λŒ€κΈ° 큐λ₯Ό μ„€μ •ν•˜κ³ , accept() ν•¨μˆ˜λ₯Ό 톡해 ν΄λΌμ΄μ–ΈνŠΈμ˜ 접속을 기닀릴 수 μžˆλ‹€

TCP ν΄λΌμ΄μ–ΈνŠΈλŠ” λ¨Όμ € μ†ŒμΌ“μ„ μƒμ„±ν•˜κ³  μ„œλ²„μ— 접속을 ν•΄μ•Όν•˜λŠ”λ°, connect() ν•¨μˆ˜λ₯Ό μ΄μš©ν•œλ‹€

μ„œλ²„μ™€ μ ‘μ†λœ ν›„μ—λŠ” read() λ‚˜ write() ν•¨μˆ˜λ₯Ό 톡해 톡신을 진행해도 되고, recv()λ‚˜ send() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄λ„ λœλ‹€

UDP 와 달리, 이미 μ„œλ²„μ— 접속해 μžˆμœΌλ―€λ‘œ 데이터λ₯Ό 보낼 λ•Œ μ„œλ²„μ˜ 정보λ₯Ό μ‚¬μš©ν•  ν•„μš”κ°€ μ—†λ‹€

TCP도 UDP 와 같이 κ΄€λ ¨ 톡신 μž‘μ—…μ΄ μ™„λ£Œλ˜λ©΄ close() ν•¨μˆ˜λ₯Ό λΆˆλŸ¬μ„œ μ†ŒμΌ“μ„ λ‹«μ•„μ£Όλ©΄ λœλ‹€

 

⭐ TCP ν΄λΌμ΄μ–ΈνŠΈ

TCP ν΄λΌμ΄μ–ΈνŠΈλŠ” μ†ŒμΌ“μ„ λ§Œλ“  후에 TCP μ„œλ²„μ— 접속해야 ν•œλ‹€

connect() ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ μ„œλ²„μ— μ ‘μ†ν•˜κ³ , write()λ‚˜ send() ν•¨μˆ˜λ₯Ό 톡해 데이터λ₯Ό 보내며 read()λ‚˜ recv() ν•¨μˆ˜λ₯Ό 톡해 데이터λ₯Ό 받을 수 μžˆλ‹€

μ„œλ²„μ™€μ˜ 톡신이 λλ‚˜λ©΄ close() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ μ—΄μ—ˆλ˜ μ†ŒμΌ“μ„ λ‹«λŠ”λ‹€

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

connect() ν•¨μˆ˜λŠ” μ„œλ²„μ˜ μ†ŒμΌ“μ— μ—°κ²°ν•˜λ©°, μ„œλ²„μ™€μ˜ 연결에 μ„±κ³΅ν•˜λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , μ„œλ²„ μ†ŒμΌ“μ΄ μ‘΄μž¬ν•˜μ§€ μ•Šκ±°λ‚˜ μ†ŒμΌ“ 큐가 가득 μ°¨ 있으면 -1을 λ°˜ν™˜ν•œλ‹€

 

μ†ŒμΌ“μ€ 파일 λ””μŠ€ν¬λ¦½ν„°λ‘œ μ·¨κΈ‰λ˜κΈ° λ•Œλ¬Έμ— read(), write() ν•¨μˆ˜λ₯Ό ν†΅ν•΄μ„œ 데이터λ₯Ό μ½κ±°λ‚˜ 보낼 수 있으며, recv()λ‚˜ send() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ 톡신을 μˆ˜ν–‰ν•  수 μžˆλ‹€

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
sszie_T send(int sockfd, const void * buf, size_T len, int flags);

 

⭐ TCP μ„œλ²„

TCP μ„œλ²„λŠ” TCP ν΄λΌμ΄μ–ΈνŠΈμ™€μ˜ 톡신을 μœ„ν•΄ μ†ŒμΌ“μ„ μƒμ„±ν•œ ν›„, bind() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 운영체제 (컀널)에 μ„œλΉ„μŠ€λ₯Ό μ—°κ²°ν•¨μœΌλ‘œμ¨ μ„œλ²„λ‘œ μ ‘μ†ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ 데어터λ₯Ό 받을 수 μžˆλ„λ‘ μ€€λΉ„ν•œλ‹€

 

ν΄λΌμ΄μ–ΈνŠΈ μ„œλΉ„μŠ€μ˜ μ€€λΉ„κ°€ μ™„λ£Œλ˜λ©΄ μ„œλ²„μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈμ˜ 접속을 μ²˜λ¦¬ν•΄μ•Ό ν•  λ©”λͺ¨λ¦¬ 곡간이 ν•„μš”ν•˜κ²Œ λœλ‹€

μ΄λ•Œ listen() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ μ—°κ²° μš”μ²­μ„ μœ„ν•œ λŒ€κΈ° 큐λ₯Ό μ„€μ •ν•  수 μžˆλ‹€

int listen(int sockfd, int backlog);

lisetn() ν•¨μˆ˜λŠ” μ—°κ²° μš”μ²­μ„ ν•  수 μžˆλŠ” μ†ŒμΌ“μ˜ μ΅œλŒ€ 수λ₯Ό λͺ…μ‹œν•˜λ©°, 이 수λ₯Ό λ„˜μ–΄μ„œλŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ μ—°κ²° μ‹œλ„λŠ” κ±°λΆ€λœλ‹€

 

μ„œλ²„μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈμ˜ 연결에 λŒ€ν•œ 곡간 (λŒ€κΈ° 큐)λ₯Ό ν™•λ³΄ν•œ ν›„μ—λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ 연결을 λŒ€κΈ°ν•΄μ•Ό ν•˜λŠ”λ°, accept() ν•¨μˆ˜λ₯Ό μ΄μš©ν•  수 μžˆλ‹€

accept() ν•¨μˆ˜λ₯Ό ν†΅ν•΄μ„œ μ„œλ²„μ— ν΄λΌμ΄μ–ΈνŠΈκ°€ μ—°κ²°λ˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈμ™€ 톡신할 수 μžˆλŠ” μ†ŒμΌ“μ— λŒ€ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ λ°˜ν™˜λœλ‹€

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);

accept() ν•¨μˆ˜μ—λŠ” μ ‘μ†ν•œ ν΄λΌμ΄μ–ΈνŠΈμ˜ 정보λ₯Ό μ–»κΈ° μœ„ν•΄ μ£Όμ†Œ ꡬ쑰체λ₯Ό μ‚¬μš©ν•œλ‹€

μ£Όμ†Œ ꡬ쑰체 ν•„λ“œ 쀑 IP와 ν¬νŠΈλŠ” λΉ… μ—”λ””μ•ˆμœΌλ‘œ μ‚¬μš©λ˜κΈ° λ•Œλ¬Έμ— 인코딩 λ³€ν™˜μ΄ ν•„μš”ν•  수 μžˆλ‹€

ν΄λΌμ΄μ–ΈνŠΈμ˜ 접속이 이뀄지면 ν΄λΌμ΄μ–ΈνŠΈμ™€μ˜ 톡신을 μœ„ν•œ μƒˆλ‘œμš΄ 포트 λ²ˆν˜Έκ°€ λ°˜ν™˜λ˜λ©° 이λ₯Ό 톡해 μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ κ°„ 톡신을 μ²˜λ¦¬ν•  수 μžˆλ‹€

 

// tcp_server.c
// TCP μ†ŒμΌ“ 기반의 톡신
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define TCP_PORT 5100 				/* μ„œλ²„μ˜ 포트 번호 */

int main(int argc, char **argv)
{
    int ssock; 					/* μ†ŒμΌ“ λ””μŠ€ν¬λ¦½νŠΈ μ •μ˜ */
    socklen_t clen;
    int n;
    struct sockaddr_in servaddr, cliaddr; 	/* μ£Όμ†Œ ꡬ쑰체 μ •μ˜ */
    char mesg[BUFSIZ];

    /* μ„œλ²„ μ†ŒμΌ“ 생성 */
    if((ssock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket()");
        return -1;
    }

    /* μ£Όμ†Œ ꡬ쑰체에 μ£Όμ†Œ 지정 */
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(TCP_PORT); 	/* μ‚¬μš©ν•  포트 지정 */

    /* bind ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ²„ μ†ŒμΌ“μ˜ μ£Όμ†Œ μ„€μ • */
    if(bind(ssock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        perror("bind()");
        return -1;
    }

    /* λ™μ‹œμ— μ ‘μ†ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ 처리λ₯Ό μœ„ν•œ λŒ€κΈ° 큐λ₯Ό μ„€μ • */
    if(listen(ssock, 8) < 0) {
        perror("listen()");
        return -1;
    }

    clen = sizeof(cliaddr);
    do {
        /* ν΄λΌμ΄μ–ΈνŠΈκ°€ μ ‘μ†ν•˜λ©΄ 접속을 ν—ˆμš©ν•˜κ³  ν΄λΌμ΄μ–ΈνŠΈ μ†ŒμΌ“ 생성 */
        int n, csock = accept(ssock, (struct sockaddr *)&cliaddr, &clen);

        /* λ„€νŠΈμ›Œν¬ μ£Όμ†Œλ₯Ό λ¬Έμžμ—΄λ‘œ λ³€κ²½ */
        inet_ntop(AF_INET, &cliaddr.sin_addr, mesg, BUFSIZ);
        printf("Client is connected : %s\n", mesg);
        if((n = read(csock, mesg, BUFSIZ)) <= 0)
            perror("read()");
        printf("Received data : %s", mesg);

        /* ν΄λΌμ΄μ–ΈνŠΈλ‘œ buf에 μžˆλŠ” λ¬Έμžμ—΄ 전솑 */
        if(write(csock, mesg, n) <= 0)
            perror("write()");
        close(csock); 			/* ν΄λΌμ΄μ–ΈνŠΈ μ†ŒμΌ“μ„ λ‹«μŒ */
    } while(strncmp(mesg, "q", 1));

    close(ssock); 			/* μ„œλ²„ μ†ŒμΌ“μ„ λ‹«μŒ */

    return 0;
}

/*
μ„œλ²„λŠ” ν΄λΌμ΄μ–ΈνŠΈλ‘œλΆ€ν„° 데이터λ₯Ό λ°›μ•„μ„œ κ·ΈλŒ€λ‘œ λ³΄λ‚΄μ£ΌλŠ” TCP 기반의 에코 μ„œλ²„
socket() ν•¨μˆ˜μ— SOCK_STREAM μ˜΅μ…˜μ„ μ‚¬μš©ν•˜μ—¬ TCP 용 μ†ŒμΌ“ λ””μŠ€ν¬λ¦½ν„°λ₯Ό μ—°λ‹€

UDP와 λ§ˆμ°¬κ°€μ§€λ‘œ ν•΄λ‹Ή ν”„λ‘œκ·Έλž¨μ„ μ„œλ²„λ‘œ μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” bind() ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ μš΄μ˜μ²΄μ œμ— μ„œλΉ„μŠ€λ₯Ό 등둝해야 ν•˜κ³ ,
bind() ν•¨μˆ˜μ˜ 두 번째 인자둜 μ„œλ²„ μžμ‹ μ˜ IP μ£Όμ†Œλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€

μ‰½κ²Œ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ INADDR_ANY λ₯Ό μ‚¬μš©ν•˜μ˜€λŠ”λ°, μ„œλ²„μ˜ IP μ£Όμ†Œλ₯Ό μžλ™μœΌλ‘œ μ°Ύμ•„μ„œ μ±„μ›Œμ€€λ‹€
ν΄λΌμ΄μ–ΈνŠΈμ˜ 톡신을 μœ„ν•œ 포트 λ²ˆν˜Έλ„ μ„€μ •ν•˜μ˜€λ‹€

ν΄λΌμ΄μ–ΈνŠΈμ˜ μ†ŒμΌ“λ“€μ„ μœ„ν•΄ λŒ€κΈ° 큐λ₯Ό μ„€μ •ν•΄μ•Ό ν•œλ‹€. listen() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ μ΅œλŒ€ 8λŒ€μ˜ ν΄λΌμ΄μ–ΈνŠΈκ°€ λ™μ‹œ 접속 λŒ€κΈ°λ₯Ό ν•  수 μžˆλ„λ‘ μ„€μ •ν•˜μ˜€λ‹€
μ†ŒμΌ“ 큐의 섀정이 λλ‚˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈμ˜ 접속을 κΈ°λ‹€λ €μ•Ό ν•˜λŠ”λ°, accept() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€

μ ‘μ†ν•œ ν΄λΌμ΄μ–ΈνŠΈμ— λŒ€ν•œ μ •λ³΄λŠ” 두 번째 인자둜 μ „λ‹¬λ˜λ©°, inet_ntop() λ“±μ˜ ν•¨μˆ˜λ‘œ μ‚¬λžŒμ΄ 읽을 수 μžˆλŠ” 문자 기반의 μ£Όμ†Œ 슀트림으둜 λ³€ν™˜ν•΄μ„œ 좜λ ₯ν•  수 μžˆλ‹€
μ‹€μ œ ν΄λΌμ΄μ–ΈνŠΈμ˜ 톡신은 accpet() ν•¨μˆ˜λ‘œ λ°˜ν™˜λ˜λŠ” μ†ŒμΌ“ λ””μŠ€ν¬λ¦½ν„°λ₯Ό μ΄μš©ν•˜κ³  read() / recv() 와 write() / send() 같은 ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ 톡신을 진행할 수 μžˆλ‹€

톡신 μž‘μ—…μ΄ λλ‚˜λ©΄ close() ν•¨μˆ˜λ‘œ μ ‘μ†λœ ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„μ˜ μ†ŒμΌ“μ„ 각각 λ‹«λŠ”λ‹€
*/
// tcp_client.c
// TCP μ†ŒμΌ“ 기반의 톡신
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define TCP_PORT 5100

int main(int argc, char **argv)
{
    int ssock;
    struct sockaddr_in servaddr;
    char mesg[BUFSIZ];

    if(argc < 2) {
        printf("Usage : %s IP_ADRESS\n", argv[0]);
        return -1;
    }

    /* μ†ŒμΌ“μ„ 생성 */
    if((ssock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket()");
        return -1;
    }

    /* μ†ŒμΌ“μ΄ 접속할 μ£Όμ†Œ 지정 */
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;

    /* λ¬Έμžμ—΄μ„ λ„€νŠΈμ›Œν¬ μ£Όμ†Œλ‘œ λ³€κ²½ */
    inet_pton(AF_INET, argv[1], &(servaddr.sin_addr.s_addr));
    servaddr.sin_port = htons(TCP_PORT);

    /* μ§€μ •ν•œ μ£Όμ†Œλ‘œ 접속 */
    if(connect(ssock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        perror("connect()");
        return -1;
    }

    fgets(mesg, BUFSIZ, stdin);
    if(send(ssock, mesg, BUFSIZ, MSG_DONTWAIT) <= 0) { 	/* 데이터λ₯Ό μ†ŒμΌ“μ— μ“΄λ‹€. */
        perror("send()");
        return -1;
    }

    memset(mesg, 0, BUFSIZ);
    if(recv(ssock, mesg, BUFSIZ, 0) <= 0) { 		/* 데이터λ₯Ό μ†ŒμΌ“μœΌλ‘œλΆ€ν„° μ½λŠ”λ‹€. */
        perror("recv()");
        return -1;
    }

    printf("Received data : %s", mesg); 		/* λ°›μ•„μ˜¨ λ¬Έμžμ—΄μ„ 화면에 좜λ ₯ */ 

    close(ssock); 					/* μ†ŒμΌ“μ„ λ‹«λŠ”λ‹€. */ 

    return 0;
}

/*
ν΄λΌμ΄μ–ΈνŠΈμ—μ„œλŠ” TCP 용 μ†ŒμΌ“μ„ μƒμ„±ν•œ ν›„ connect() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ²„μ— μ ‘μ†ν•œλ‹€
connect() ν•¨μˆ˜μ—λŠ” μ„œλ²„ μ£Όμ†Œμ— λŒ€ν•œ 정보λ₯Ό λͺ…μ‹œν•œλ‹€
기본적인 μ£Όμ†Œ μ„€μ • 방법은 bind() ν•¨μˆ˜μ™€ λ™μΌν•˜μ§€λ§Œ, connect() ν•¨μˆ˜λŠ” INADDR_ANY λ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€ (포트 λ²ˆν˜ΈλŠ” μ„œλ²„μ™€ 같은 번호λ₯Ό μ‚¬μš©)

μ„œλ²„μ— μ ‘μ†ν•œ ν›„ fgets() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ ν‚€λ³΄λ“œλ‘œ 데이터λ₯Ό 받아듀인 ν›„, μ•žμ—μ„œ μƒμ„±ν•œ μ†ŒμΌ“μ„ μ΄μš©ν•˜μ—¬ send() λ‚˜ write() ν•¨μˆ˜λ₯Ό 톡해 μ„œλ²„λ‘œ 데이터λ₯Ό 보내고,
resv() λ‚˜ read() ν•¨μˆ˜λ₯Ό 톡해 데이터λ₯Ό λ°›λŠ”λ‹€. printf() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ„œ μ„œλ²„λ‘œλΆ€ν„° 받은 데이터λ₯Ό 화면에 ν‘œμ‹œν•˜μ˜€λ‹€

μ•žμ˜ μ½”λ“œλ₯Ό λΉŒλ“œν•˜κ³  λ¨Όμ € μ„œλ²„λ₯Ό μ‹€ν–‰μ‹œν‚¨λ‹€. UDP 와 λ§ˆμ°¬κ°€μ§€λ‘œ ν΄λΌμ΄μ–ΈνŠΈλ₯Ό ν•¨κ»˜ μ‹€ν–‰ν•˜λ €λ©΄ λ‹€λ₯Έ 터미널이 ν•„μš”ν•˜λ―€λ‘œ λ‹€λ₯Έ 터미널을 μ—΄κ³  둜그인 OR μ„œλ²„λ₯Ό λ°±κ·ΈλΌμš΄λ“œλ‘œ γ…£γ„Ήν–‰
같은 라즈베리파이/PC μ—μ„œ μ‹€ν–‰λ˜κ³  μžˆλŠ” μ„œλ²„λ‘œ 접속할 λ•ŒλŠ” μ„œλ²„μ˜ 127.0.0.1을 μž…λ ₯ν•œλ‹€

ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ λ¬Έμžμ—΄μ„ μž…λ ₯ν•˜λ©΄ TCP λ₯Ό ν†΅ν•΄μ„œ ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ 간에 톡신이 이뀄진닀
ν΄λΌμ΄μ–ΈνŠΈλŠ” λ¨Όμ € μ„œλ²„λ‘œ λ¬Έμžμ—΄μ„ 보내면 μ„œλ²„μ—μ„œλŠ” λ¬Έμžμ—΄μ„ 읽고 λ‹€μ‹œ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λ˜λŒλ €μ€€λ‹€
ν΄λΌμ΄μ–ΈνŠΈλŠ” μ„œλ²„λ‘œλΆ€ν„° μ „λ‹¬λœ 데이터λ₯Ό λ°›μ•„μ„œ 화면에 좜λ ₯ν•˜κ³  μ„œλ²„λ₯Ό μ’…λ£Œν•˜κ³  싢을 λ•ŒλŠ” 클라이언틀λ₯΄ μ‹œμž‘ν•˜κ³  q λ₯Ό μž…λ ₯ν•˜λ©΄ λœλ‹€
*/
gcc -o tcp_server tcp_server.c 
gcc -o tcp_client tcp_client.c 
./tcp_server &
./tcp_client 127.0.0.1

 

⭐ μš°μ•„ν•œ μ—°κ²° μ’…λ£Œ: shutdown() ν•¨μˆ˜

close() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ„œλ²„μ—μ„œμ˜ 읽기 / 좜λ ₯ 용 μ†ŒμΌ“μ„ λͺ¨λ‘ λ‹«λŠ”λ‹€

shutdown() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ κ²½μš°μ— 따라 읽기 μ†ŒμΌ“λ§Œ λ‹«κ±°λ‚˜, μ“°κΈ° μ†ŒμΌ“λ§Œ 닫을 수 μžˆλ‹€

int shutdown(int sockfd, int how);

 

shutdown() ν•¨μˆ˜μ˜ 두 번째 인자(how) λ₯Ό 톡해 μ½κ±°λ‚˜ μ“°κΈ° ν˜Ήμ€ 읽기/μ“°κΈ° 용 μ†ŒμΌ“μ„ λͺ¨λ‘ 닫을 수 μžˆλ‹€

shutdown() ν•¨μˆ˜μ— SHUT_RDWR 을 μ΄μš©ν•˜λ©΄ close() ν•¨μˆ˜μ²˜λŸΌ μž…/좜λ ₯ μŠ€νŠΈλ¦Όμ„ λͺ¨λ‘ λ‹«λŠ”λ°, close() ν•¨μˆ˜μ™€ 달리 별닀λ₯Έ μž‘μ—… 없이 λ°”λ‘œ μ’…λ£Œμ‹œν‚¨λ‹€

μƒμˆ«κ°’ λͺ¨λ“œ λ‚΄μš©
0 SHUT_RD μž…λ ₯ 슀트림 μ’…λ£Œ
1 SHUT_WR 좜λ ₯ 슀트림 μ’…λ£Œ
2 SHUT_RDWR μž…/좜λ ₯ 슀트림 μ’…λ£Œ

 

ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ—μ„œλŠ” 데이터λ₯Ό 내보낸 후에 shutdown() ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ μ†ŒμΌ“μ˜ μ“°κΈ° μŠ€νŠΈλ¦Όμ„ λ‹«κ³  (SHUT_WR), 데이터λ₯Ό 읽은 ν›„μ—λŠ” μ†ŒμΌ“ 읽기 μŠ€νŠΈλ¦Όμ„ 닫을 수 μžˆλ‹€ (SHUT_RD)

 

 

 

728x90
λ°˜μ‘ν˜•
Comments