반응형




  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <errno.h>  
  5. #include <string.h>  
  6. #include <sys/types.h>  
  7. #include <sys/socket.h>  
  8. #include <netinet/in.h>  
  9. #include <netdb.h>  
  10. #include <arpa/inet.h>  
  11. #include <sys/wait.h>  
  12. #include <pthread.h>  
  13. #include <signal.h>  
  14.   
  15.   
  16. struct thread_data{  
  17.     int fd;  
  18.     char ip[20];  
  19. };  
  20.   
  21. void *ThreadMain(void *argument);  
  22.   
  23.   
  24. // get sockaddr, IPv4 or IPv6:  
  25. void *get_in_addr(struct sockaddr *sa)  
  26. {  
  27.     if (sa->sa_family == AF_INET) {  
  28.         return &(((struct sockaddr_in*)sa)->sin_addr);  
  29.     }  
  30.   
  31.     return &(((struct sockaddr_in6*)sa)->sin6_addr);  
  32. }  
  33.   
  34. int main(void)  
  35. {  
  36.     int sockfd, new_fd;    
  37.     struct sockaddr_storage client_addr;  
  38.     struct sockaddr_in servaddr;  
  39.     socklen_t sin_size;  
  40.     char address[20];  
  41.     int ret;  
  42.   
  43.     pthread_t thread_id;  
  44.   
  45.   
  46.     //이미 연결이 종료된 클라이언트에 Send하려고 했을따 나오는 시그널을  
  47.     //처리해주지 않으면 기본 동작은 프로그램 종료라서 서버가 다운된다.   
  48.     //클라이언트가 비정상적인 종료를 했을때 broken pipe signal이 발생하고   
  49.     //클라이언트 종료를 서버에서 제어할수 없기때문에 해당 시그널을 무시  
  50.     //하도록 해주어야 한다.   
  51.     //http://egloos.zum.com/nomoreid/v/1169779  
  52.     signal( SIGPIPE, SIG_IGN );  
  53.   
  54.       
  55.     sockfd = socket(AF_INET, SOCK_STREAM,0);  
  56.   
  57.     bzero( &servaddr, sizeof(servaddr));  
  58.     servaddr.sin_family = AF_INET;  
  59.     servaddr.sin_addr.s_addr = INADDR_ANY;  
  60.     unsigned int port = 9999;  
  61.     servaddr.sin_port = htons(port);  
  62.   
  63.     ret = bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));  
  64.     if ( ret != 0 )  
  65.     {  
  66.         perror("bind");  
  67.         exit(-1);  
  68.     }  
  69.   
  70.     ret = listen(sockfd, 5);  
  71.     if ( ret != 0 )  
  72.     {  
  73.         perror("listen");  
  74.         exit(-1);  
  75.     }  
  76.   
  77.   
  78.     while(1) {  // main accept() loop  
  79.   
  80.         printf( "i am wait new client \n" );  
  81.       
  82.         sin_size = sizeof client_addr;  
  83.         new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);  
  84.         if (new_fd == -1) {  
  85.             perror("accept");  
  86.             continue;  
  87.         }  
  88.   
  89.         inet_ntop(client_addr.ss_family,  
  90.             get_in_addr((struct sockaddr *)&client_addr),  
  91.             address, sizeof address);  
  92.         printf("server: got connection from %s\n", address);  
  93.           
  94.         struct thread_data *data;  
  95.         data= (struct thread_data*)malloc(sizeof(struct thread_data));    
  96.         data->fd = new_fd;  
  97.         strcpy( data->ip,address);   
  98.   
  99.         pthread_create( &thread_id, NULL, ThreadMain, (void*)data);  
  100.     }  
  101.   
  102.     return 0;  
  103. }  
  104.   
  105. void *ThreadMain(void *argument)  
  106. {  
  107.     struct thread_data *client_data;  
  108.     char buf[1024];  
  109.   
  110.   
  111.     pthread_detach(pthread_self());  
  112.     client_data = (struct thread_data*)argument;  
  113.     int fd = client_data->fd;  
  114.     char ip[20];  
  115.     strcpy( ip, client_data->ip);  
  116.   
  117.     while(1)  
  118.     {  
  119.         int num;  
  120.         num = read( fd, buf, sizeof(buf) );  
  121.   
  122.         //클라이언트가 갑자기 끊어버리면 read함수는 0을 리턴한다.  
  123.         if ( num == 0 ) break;  
  124.   
  125.         printf("recv : [%s] %dbyte\n", buf, num );  
  126.   
  127.         write( fd, buf, strlen(buf));  
  128.     }  
  129.   
  130.     printf("disconnected client ip %s\n", ip );  
  131.     free(client_data);  
  132.     close(client_data->fd);  
  133.   
  134.     return 0;     
  135. }  



참고 

https://computing.llnl.gov/tutorials/pthreads/

http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Thread/Beginning/Example_pthread

http://egloos.zum.com/nomoreid/v/1169779

http://beej.us/guide/bgnet/output/html/multipage/index.html





반응형

포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

여러분의 응원으로 좋은 컨텐츠가 만들어집니다.
지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

유튜브 구독하기


제가 쓴 책도 한번 검토해보세요.

+ Recent posts