[Part 1] 소켓 프로그래밍 시작하기

이유진·2023년 11월 21일
0

TCP 통신

목록 보기
1/2

장석용의 TCP/IP 소켓 프로그래밍 이라는 책을 보고 네트워크 과제를 해볼거야!!
교재가 2009년에 만들어져서 그런지 교재 코드 그대로 실행하면 오류난다.
대부분 여러 라이브러리 함수들을 사용하기 위해 필요한 헤더 파일을 인클루드하지 않아서 나는 오류였다.

아래는 수정된 코드다!!

1️⃣ 클라이언트와 연결되자마자 서버 프로그램이 문자열 전송하고 클라이언트 프로그램이 받아 출력하기

hello_server.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 9000

char buffer[BUFSIZ] = "hello, world";

int main() {
    int c_socket, s_socket;
    struct sockaddr_in s_addr, c_addr;
    socklen_t len; // Changed the type of len variable

    s_socket = socket(PF_INET, SOCK_STREAM, 0);

    memset(&s_addr, 0, sizeof(s_addr));
    s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(PORT);

    if (bind(s_socket, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1) {
        printf("Can not Bind\n");
        return -1;
    }

    if (listen(s_socket, 5) == -1) {
        printf("listen Fail\n");
        return -1;
    }

    while (1) {
        len = sizeof(c_addr);
        c_socket = accept(s_socket, (struct sockaddr *)&c_addr, &len); // Passing &len with correct type

        int n = strlen(buffer);
        write(c_socket, buffer, n);

        close(c_socket);
    }
    close(s_socket);
    return 0;
}

hello_client.c

#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 9000
#define IPADDR "127.0.0.1"

int main() {
    int c_socket;
    struct sockaddr_in c_addr;
    int len;
    int n;
    
    char rcvBuffer[BUFSIZ];
    
    c_socket = socket(PF_INET, SOCK_STREAM, 0);
    
    memset(&c_addr, 0, sizeof(c_addr));
    c_addr.sin_addr.s_addr = inet_addr(IPADDR);
    c_addr.sin_family = AF_INET;
    c_addr.sin_port = htons(PORT);
    
    if(connect(c_socket, (struct sockaddr *) &c_addr, sizeof(c_addr)) == -1) {
        printf("Can not connect\n");
        close(c_socket);
        return -1;
    }
    
    if((n = read(c_socket, rcvBuffer, sizeof(rcvBuffer))) < 0) {
        return (-1);
    }
    
    rcvBuffer[n] = '\0';
    printf("received Data : %s\n", rcvBuffer);
    
    close(c_socket);
    
    return 0;
}

gcc -o hello_server hello_server.c ./hello_server
이렇게 서버를 실행시키고

gcc -o hello_client hello_client.c ./hello_client
이렇게 클라이언트에서도 실행하면 서버측에서 전송한 문자열 hello, world 데이터를 받을 수 있다!!

서버 과정

  1. 소켓 생성
  2. 연결 요청을 수신할 주소 설정
  3. 소켓을 포트에 연결
  4. 커널(운영체제)에 개통 요청
  5. 클라이언트로부터의 연결 요청을 수신
  6. 클라이언트에게 서비스 제공
  7. 클라이언트와의 연결 종료
  8. 서버 종료

클라이언트 과정

  1. 소켓 생성
  2. 연결할 서버의 주소 설정
  3. 소켓을 서버에 연결
  4. 서비스 요청과 처리
  5. 소켓 연결 종료

2️⃣ 클라이언트 프로그램이 문자열 print를 보내면 서버 프로그램이 이 요청을 받아야 문자열(hello, world) 출력하기

<과정>
1. 연결 요청 (client -> server)
2. print 요청 (client -> server 로 print 전송)
3. 문자열 전송 (server -> client)
4. 화면 출력

hello_server.c

#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>

#define PORT 9000
#define BUFSIZE 1024

char buffer[BUFSIZE] = "hello, world";

int main() {
    int c_socket, s_socket;
    struct sockaddr_in s_addr, c_addr;
    int len;
    int n;

    s_socket = socket(PF_INET, SOCK_STREAM, 0);

    memset(&s_addr, 0, sizeof(s_addr));
    s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(PORT);

    if (bind(s_socket, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1) {
        printf("Can not Bind\n");
        return -1;
    }

    if (listen(s_socket, 5) == -1) {
        printf("listen Fail\n");
        return -1;
    }

    while (1) {
        len = sizeof(c_addr);
        c_socket = accept(s_socket, (struct sockaddr *)&c_addr, &len);

        char rBuffer[BUFSIZE];
        int length = 0;
        char *temp = rBuffer;

        while ((n = read(c_socket, temp, 1)) > 0) {
            if (*temp == '\r') continue;
            if (*temp == '\n') break;
            if (*temp == '\0') break;

            if (length == BUFSIZE) break;
            temp++;
            length++;
        }

        rBuffer[length] = '\0';

        if (!strcmp(rBuffer, "print")) {
            n = strlen(buffer);
            write(c_socket, buffer, n);
        }

        close(c_socket);
    }

    close(s_socket);
    return 0;
}

hello_client.c

#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 9000
#define IPADDR "127.0.0.1"

char buffer[BUFSIZ];

int main() {
    int c_socket;
    struct sockaddr_in c_addr;
    int len;

    char rcvBuffer[BUFSIZ];
    int n;

    c_socket = socket(PF_INET, SOCK_STREAM, 0);

    memset(&c_addr, 0, sizeof(c_addr));
    c_addr.sin_addr.s_addr = inet_addr(IPADDR);
    c_addr.sin_family = AF_INET;
    c_addr.sin_port = htons(PORT);

    if (connect(c_socket, (struct sockaddr *)&c_addr, sizeof(c_addr)) == -1) {
        printf("Can not connect\n");
        close(c_socket);
        return -1;
    }

    printf("Enter a message: ");
    scanf("%s", buffer);
    buffer[sizeof(buffer) - 1] = '\0'; // Ensure null-termination and prevent buffer overflow
    write(c_socket, buffer, strlen(buffer) + 1);

    if ((n = read(c_socket, rcvBuffer, sizeof(rcvBuffer))) < 0) {
        return -1;
    }

    rcvBuffer[n] = '\0';
    printf("received Data : %s\n", rcvBuffer);

    close(c_socket);
    return 0;
}

profile
안녕하세요

0개의 댓글