Ping server & Ping clinet
이전에 공부한 socket, bind, listen, accept, connect 등의 함수를 이용해 간단한 echo 서버를 만들었다.
기본적인 골격은 아래와 같다.
서버에서 연결 준비를 거친 뒤 클라이언트에서 연결한다.
이후 클라이언트에서 write 함수를 통해 입력 받은 값을 서버에게 전달한다.
서버는 전달 받은 데이터를 read 함수를 통해 한번 읽어 저장한 뒤 write 함수로 클라이언트에게 전달한다.
서버로부터 데이터를 전달 받은 클라이언트는 read 함수를 통해 정보를 저장한 뒤 다시 데이터를 입력 받을 준비를 한다.
지속적으로 데이터를 읽고 쓰는 방식은 read 와 write 함수 부분에 while 문을 넣는 아주 간단한 방식을 사용했다.
Server Side Code
단계 (해당 함수 혹은 구조체 명)
소켓을 연다 (socket)
> 서버에 주소를 할당한다(sturct sockaddr_in)
> 서버를 연다 (bind)
> 연결을 기다린다.(listen)
> 연결이 오면 허가한다.(accept)
> 데이터를 주고 받는다.(read/write)
> 연결을 종료한다. (close)
#include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> enum{CMD, PORT}; int main(int argc, char * argv[]) { int sock, sock_clinet; int sock_client_len; struct sockaddr_in sock_addr, sock_clinet_addr; char buf[1024]; if(argc != 2){ printf("Usage %s <PORT>\n",argv[CMD]); exit(1); } // 소켓을 {{ sock=socket(AF_INET,SOCK_STREAM,0); if(sock < 0){ perror("socket "); exit(1); } // }} 여는 부분 // 서버의 주소를{{ memset(&sock_addr,0x00,sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = htons(INADDR_ANY); //INADDR_ANY는 실행 중인 컴퓨터에 IP 주소를 의미한다. sock_addr.sin_port=htons(atoi(argv[PORT])); // }} 설정하는 부분 // 설정된 주소로 {{ if(bind(sock,(struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0){ perror("bind "); exit(1); } // }} 서버를 여는 부분 // 연결을 {{ if(listen(sock,5) < 0){ perror("listen "); exit(1); } // }} 기다리는 부분 // 클라이언트의 연결을 {{ sock_client_len = sizeof(sock_clinet_addr); sock_clinet = accept(sock,(struct sockaddr *)&sock_clinet_addr, &sock_client_len); if(sock_clinet < 0){ perror("accept "); exit(1); } // 받는 부분 // 데이터를 {{ while(1){ if(read(sock_clinet,buf,sizeof(buf)) < 1){ perror("read "); exit(1); } printf("====Ping data====\n%s\n====================\n", buf); if(write(sock_clinet,buf,sizeof(buf))<0){ perror("write "); exit(1); } } // }} 주고 받는 부분 close(sock_clinet); close(sock); return 0; }
Client Side Code
소켓을 연다 (socket)
> 서버 주소를 삽입한다(sturct sockaddr_in)
> 서버에게 요청한다. (connect)
> 데이터를 주고 받는다.(read/write)
> 연결을 종료한다. (close)
#include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> enum{CMD, IP, PORT}; int main(int argc, char * argv[]) { int sock; struct sockaddr_in sock_addr; char buf[1024]; if(argc != 3){ printf("Useage: %s <IP> <PORT>\n", argv[CMD]); exit(1); } // 소켓을 {{ sock=socket(AF_INET,SOCK_STREAM,0); if(sock < 0){ perror("socket "); exit(1); } // }} 여는 부분 // 주소를 {{ memset(&sock_addr,0x00,sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = inet_addr(argv[IP]); sock_addr.sin_port=htons(atoi(argv[PORT])); // }} 설정하는 부분 // 설정된 주소로 {{ if(connect(sock,(struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0){ perror("connect "); exit(1); } // }} 연결하는 부분 // 데이터를 {{ while(1){ printf("Input string :"); scanf("%s",buf); if(write(sock,buf,sizeof(buf))<0){ perror("write "); exit(1); } if(read(sock,buf,sizeof(buf))<0){ perror("read "); exit(1); } printf("====Pong data====\n%s\n====================\n", buf); } // }} 주고 받는 부분 close(sock); return 0; }