본문 바로가기
Programming/C

Linux c socket 통신 테스트 (recv 할 데이터가 더 클 경우)

by jjayheony 2025. 4. 14.
반응형

Linux 에서 C 언어로 socket 통신하는 예제를 작성 해보았다.

(OS : Rocky Linux 9.5)

여기서 궁금했던 것은 recv 함수를 실행 시에 받을 데이터가 100 byte 이고, 실제로 받은 데이터가 50 byte 라고 하면 어떻게 될 지 궁금했다. 50 byte 를 받고 recv 로 대기를 할 지 아니면 50 byte 만 수행할 지 궁금했다.

recv(클라이언트 소켓 fd, 받을 버퍼, 받을 사이즈, 옵션) 이니까

받을 사이즈를 100으로 설정하였고,

send(서버 소켓, 보낼 버퍼, 보낼 사이즈, 옵션) 

에서 보낼 사이즈를 50 으로 설정한 코드이다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>

#include "../common/tcp_data.h"

int main (int argc, char **argv)
{
  if (argc != 2)
  {
    printf("Usage : %s <option> : svr or cli\n", argv[0]);
    exit(1);
  }

  if (strcmp(argv[1], "svr") == 0)
  {
    int sockfd; 
    long rlen;
    char buffer[1024];
    struct sockaddr_in servAddr, clntAddr;
    int clntSockfd, clntLen;
    clntLen = sizeof(clntAddr);

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
      printf("<!> socket fail\n");
      return -1;
    }

    memset(&servAddr, 0, sizeof(servAddr));
    memset(buffer, 0x00, 1024);

    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servAddr.sin_port = htons(8888);

    if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1)
    {
      printf("<!> bind fail\n");
      return -1;
    }

    if (listen(sockfd, 5) == -1)
    {
      printf("<!> listen fail\n");
      return -1;
    }

    if ((clntSockfd = accept(sockfd, (struct sockaddr*)&clntAddr, &clntLen)) == -1)
    {
      printf("<!> accept fail\n");
      return -1;
    }

    if ((rlen = recv(clntSockfd, buffer, 100, 0)) == -1)
    {
      printf("<!> recv_data fail\n");
      printf(">> rlen : %ld\n", rlen);
      printf(">> errno : %d\n", errno);
      printf(">> error : %s\n", strerror(errno));
      close(sockfd);
      close(clntSockfd);
      return -1;
    }
    printf(">> rlen : %ld\n", rlen);
    printf(">> data : %s\n", buffer);
    close(clntSockfd);
  }
  else if (strcmp(argv[1], "cli") == 0)
  {
    int sockfd;
    long slen;
    char ip[1024] = "127.0.0.1";
    char buf[1024] = "Hello, Server!";
    struct sockaddr_in servAddr;

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
      printf("<!> socket fail\n");
      return -1;
    }

    memset(&servAddr, 0, sizeof(servAddr));

    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = inet_addr(ip);
    servAddr.sin_port = htons(8888);

    if (connect(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1)
    {
      printf("<!> connect failed\n");
      return -1;
    }

    if (slen = send(sockfd, buf, 50, 0) == -1)
    {
      printf("<!> send fail");
      return -1;
    }

    close(sockfd);
  }
  else
  {
    printf("Unknown option : %s\n", argv[1]);
    return -1;
  }

  return 0;
}

 

실행 방법은 아래와 같다.

# 빌드
gcc test.c

# 서버 실행
./a.out svr

# 클라이언트 실행 (서버와 다른 터미널)
./a.out cli

 

50 byte 를 받고 data를 출력하고 끝난다.

즉, 100 byte 보다 적더라도 보낸 byte 만큼 읽고 끝난다.

반응형