TCP 에코 서버 샘플 소스 입니다. 여기 저기 블로그에 있는 것들을 짜집기 해서 작성해 보았습니다. 공부 삼아 한번 검색을 해봤는데요. 인터넷에 떠돌아 다니는 소스들중에 깔끔한 소스를 찾지 못했습니다.  조금씩 소스를 짜집기 해보았습니다. 그렇다고 지금 소스가 완벽한 소스란 말은 아닙니다. 저도 대충 눈에 보이는 부분만 수정을 해서 돌아가기만 합니다. 예외 처리리는 차차... 


 소스에 주석도 없는데요. 업그레이드 된 모습으로 다시한번 소스를 정리와 주석을 첨부해서 포스팅하도록 하겠습니다. 드래그가 힘드신분을 위해 파일도 첨부합니다. 


tcp_echo_client.c

tcp_echo_server.c




  서버 코드 (echo server)

UltraEdit source file - ����1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

#define BUF_SIZE 1024                     
void Error_handling(char* message);      


int main(int argc, char* argv[])           
{
  WSADATA wsaData;                         
  SOCKET serv_sock, clnt_sock;         
  SOCKADDR_IN serv_addr, clnt_addr;  

  int strLen;
  char message[BUF_SIZE] ={0,};      
  char data[BUF_SIZE] = {0,};
  int clntAdrSize;
  
  if(argc != 2)
  {
    printf("Usage %s <port> \n", argv[0]);
    exit(1);
  }
  if( WSAStartup( MAKEWORD(2, 2), &wsaData) !=0 )  
    Error_handling("WSAStartup() Error!");


  serv_sock = socket(PF_INET, SOCK_STREAM, 0);   
  
  if(serv_sock == INVALID_SOCKET)
    Error_handling("socket() error");
  
  memset(&serv_addr, 0, sizeof(serv_addr));           
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(atoi(argv[1]));
  
  if( bind(serv_sock, (SOCKADDR*) &serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) 
    Error_handling("bind() error!");
  
  if( listen(serv_sock, 5) == SOCKET_ERROR)       
    Error_handling("listen() error!");
  
  clntAdrSize = sizeof(clnt_addr);                        
  
  
  
  while(1)
  {
    clnt_sock = accept(serv_sock, (SOCKADDR*) &clnt_addr, &clntAdrSize);  
    
    if(clnt_sock == -1)
      Error_handling("accept() error!");
    
    else
      printf("Accept client \n"); 
    
    while((strLen = recv(clnt_sock, message, BUF_SIZE, 0)) !=0)       
    {   
      if (strLen == -1)
      {
        printf("disconnect  client \n"); 
        break;
        
      }
      memset(data, 0, BUF_SIZE);
      memcpy(data,message, strLen);
      printf("data:%s  recv_len = %d \n", message, strLen);
      send(clnt_sock, message, strLen, 0);
    }
    
    closesocket(clnt_sock);
  
  }

  


  closesocket(serv_sock);
  WSACleanup();
  return 0;
}


void Error_handling(char* message)
{
  fputs(message, stderr);
  fputc('\n', stderr);
  exit(1);
}



  클라이언트 (echo client)

UltraEdit source file - ����2
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>

#pragma comment (lib,"ws2_32.lib")

#define BUFSIZE 512


void err_display(char *msg);
void err_quit(char *msg);
int recvn(SOCKET s, char* buf,int len,int flags);

int main(int argc, char * argv[])
{
  SOCKET sock;
  SOCKADDR_IN serveraddr;

  int retval;
  char buf[BUFSIZE+1];
  int len;
  WSADATA wsa;
  
  if(argc != 3 )
  {
    printf("Usage %s <port> \n", argv[0]);
    exit(1);
  }

  
  if(WSAStartup(MAKEWORD(2,2),&wsa) != 0) 
    return -1;

  sock = socket(AF_INET,SOCK_STREAM,0);
  if(sock == INVALID_SOCKET) err_quit("sock()");
  
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
  serveraddr.sin_port = htons(atoi(argv[2]));
  
  retval = connect(sock,(SOCKADDR*)&serveraddr,sizeof(serveraddr));
  if(retval == SOCKET_ERROR) err_quit("connect()");

  while(1)
  {

    ZeroMemory(buf,sizeof(buf));
    printf("send To server : ");
    if(fgets(buf,BUFSIZE+1,stdin)==NULL)
      break;


    len = strlen(buf);
    if(buf[len-1] == '\n')
      buf[len-1] = '\0';
    if(strlen(buf)==0)
      break;


    retval = send(sock,buf,strlen(buf),0);
    if(retval == SOCKET_ERROR)
    {
      err_display("send()");
      break;
    }
    printf("recv len %d \n",retval);

  
    retval = recvn(sock,buf,retval,0);
    if(retval==SOCKET_ERROR)
    {
      err_display("recv()");
      break;
    }
    else if(retval==0)
      break;

  
    buf[retval] = '\0';
    printf("data:%s  len%d \n", buf, retval);
    
  }

  closesocket(sock);
  WSACleanup();

  return 0;
}

int recvn(SOCKET s, char* buf,int len,int flags)
{
  int received;
  char* ptr = buf;
  int left = len;
  

  while(left > 0)
  {
    received = recv(s,ptr,left,flags);
    if(received == SOCKET_ERROR)
      return SOCKET_ERROR;
    else if(received == 0)
      break;
    left -= received;
    ptr += received;
  }
  return (len-left);
}

void err_display(char *msg)
{
  LPVOID lpMsgBuf;
  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    FORMAT_MESSAGE_FROM_SYSTEM,
    NULL, WSAGetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR)&lpMsgBuf,0,NULL);
  printf("[%s] %s",msg,(LPTSTR)lpMsgBuf);
  LocalFree(lpMsgBuf);
}

void err_quit(char *msg)
{
  LPVOID lpMsgBuf;
  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    FORMAT_MESSAGE_FROM_SYSTEM,
    NULL, WSAGetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR)&lpMsgBuf,0,NULL);
  MessageBox(NULL,(LPTSTR)lpMsgBuf,msg,MB_ICONERROR);
  LocalFree(lpMsgBuf);
  exit(-1);
}


실행 결과