๐Ÿ˜Ž ๊ณต๋ถ€ํ•˜๋Š” ์ง•์ง•์•ŒํŒŒ์นด๋Š” ์ฒ˜์Œ์ด์ง€?

[๋ฆฌ๋ˆ…์Šค ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ] 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