Describe 권ì˜ê¸°/채팅프로그램 here ["2012/3/30 - ì¼ëŒ€ì¼ 채팅 프로그램 만들기"] ["2012/4/3 - 멀티채팅 프로그램 만들기"] === 2012/3/30 - ì¼ëŒ€ì¼ 채팅 프로그램 만들기 === == 설명 == 서버ì—ì„œë„ ë©”ì„¸ì§€ë¥¼ 보낼 수 ìžˆê³ , í´ë¼ì´ì–¸íŠ¸ì—ì„œë„ ë©”ì„¸ì§€ë¥¼ 보낼 수 있습니다. exit를 치면 ì±„íŒ…ì„ ì¢…ë£Œí•©ë‹ˆë‹¤. == ë¬¸ì œì == exit를 ì³¤ì„ ë•Œ, 종료가 ì œëŒ€ë¡œ ë˜ì§€ 않는 ê²ƒì´ ë¬¸ì œìž…ë‹ˆë‹¤. clientì—ì„œ exit를 ì³¤ì„ ë•Œ, "ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤." ë¼ëŠ” 메세지가 바로 뜨지 않습니다. serverì—ì„œ 아무거나 ìž…ë ¥í•˜ë©´ ê·¸ì œì„œì•¼ clientì—ì„œ "ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤."ê°€ ì¶œë ¥ë©ë‹ˆë‹¤. ê·¸ë¦¬ê³ ë‚˜ì„œ server는 채팅 종료ì§ì „ì— ë°›ì•˜ë˜ ë©”ì„¸ì§€ë¥¼ 무한히 ì¶œë ¥í•©ë‹ˆë‹¤. serverì—ì„œ exit를 ì³¤ì„ ë•Œ, "ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤." ë¼ëŠ” 메세지가 바로 뜨지 않습니다. clientì—ì„œ 아무거나 ìž…ë ¥í•˜ë©´ ê·¸ì œì„œì•¼ serverì—ì„œ "ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤."ê°€ ì¶œë ¥ë©ë‹ˆë‹¤. ê·¸ë¦¬ê³ ë‚˜ì„œ client는 채팅 종료ì§ì „ì— ë°›ì•˜ë˜ ë©”ì„¸ì§€ë¥¼ 무한히 ì¶œë ¥í•©ë‹ˆë‹¤. 무한 ë£¨í”„ì— ê´€í•œ ë¬¸ì œëŠ” í•´ê²°ë˜ì—ˆìŠµë‹ˆë‹¤. - 2012. 4. 3 == 서버 == {{{ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/socket.h> #include<pthread.h> #define SIZE 1024 int client_socket, server_socket; int client_addr_size, flag = 0; char buff_snd[SIZE + 5], buff_rcv[SIZE + 5]; void* snd(void *data){ while(!flag){ gets(buff_rcv); if(strcmp(buff_rcv, "exit") == 0)flag = 1; else{ sprintf( buff_snd, "%d : %s", strlen( buff_rcv), buff_rcv); send(client_socket, buff_snd, strlen(buff_snd)+1, 0); } } } void *rcv(void *data){ int temp; while(!flag){ if(recv(client_socket, buff_rcv, SIZE, 0) <= 0)continue; else{ if(strcmp(buff_rcv, "exit") == 0)flag = 1; else{ printf( "receive: %s\n", buff_rcv); sprintf( buff_snd, "%d : %s", strlen( buff_rcv), buff_rcv); } } } } int main(void){ int option = 1; pthread_t pthread[2]; struct sockaddr_in server_addr, client_addr; server_socket = socket(PF_INET, SOCK_STREAM, 0); setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); if (-1 == server_socket) { printf( "server socket ìƒì„± 실패"); exit( 1) ; } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(4000); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr))){ printf( "bind() 실행 ì—러\n"); exit( 1); } if(listen(server_socket, 5) == -1){ printf( "대기ìƒíƒœ 모드 ì„¤ì • 실패\n"); exit( 1); } client_addr_size = sizeof(client_addr); client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_size); if(client_socket == -1){ printf( "í´ë¼ì´ì–¸íŠ¸ ì—°ê²° ìˆ˜ë½ ì‹¤íŒ¨\n"); exit(1); } pthread_create(&pthread[0], NULL, snd, (void *)NULL); pthread_create(&pthread[1], NULL, rcv, (void *)NULL); int status; pthread_join(pthread[0], (void**)&status); pthread_join(pthread[1], (void**)&status); printf("ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤.\n"); close(server_socket); return 0; } }}} == í´ë¼ì´ì–¸íŠ¸ == {{{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #define SIZE 1024 int flag = 0; char buff_snd[SIZE + 5], buff_rcv[SIZE + 5]; int client_socket; void* snd(void *data){ while(!flag){ gets(buff_rcv); if(strcmp(buff_rcv, "exit") == 0)flag = 1; else{ sprintf( buff_snd, "%d : %s", strlen( buff_rcv), buff_rcv); send(client_socket, buff_snd, strlen(buff_snd)+1, 0); } } } void *rcv(void *data){ int temp; while(!flag){ if(recv(client_socket, buff_rcv, SIZE, 0) <= 0)continue; else{ if(strcmp(buff_rcv, "exit") == 0)flag = 1; else{ printf( "receive: %s\n", buff_rcv); sprintf( buff_snd, "%d : %s", strlen( buff_rcv), buff_rcv); } } } } int main( int argc, char **argv) { pthread_t pthread[2]; struct sockaddr_in server_addr; client_socket = socket( PF_INET, SOCK_STREAM, 0); if( -1 == client_socket) { printf( "socket ìƒì„± 실패\n"); exit( 1); } memset( &server_addr, 0, sizeof( server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons( 4000); server_addr.sin_addr.s_addr= inet_addr( "127.0.0.1"); if( -1 == connect( client_socket, (struct sockaddr*)&server_addr, sizeof( server_addr) ) ) { printf( "ì ‘ì† ì‹¤íŒ¨\n"); exit( 1); } pthread_create(&pthread[0], NULL, snd, (void *)NULL); pthread_create(&pthread[1], NULL, rcv, (void *)NULL); int status; pthread_join(pthread[0], (void**)&status); pthread_join(pthread[1], (void**)&status); printf("ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤.\n"); close(client_socket); return 0; } }}} === 2012/4/3 - 멀티채팅 프로그램 만들기 === == 설명 == 멀티 ì±„íŒ…ì´ ë©ë‹ˆë‹¤. ì´ì „ì— ìž‘ì„±í–ˆë˜ ì¼ëŒ€ì¼ 채팅 í”„ë¡œê·¸ëž¨ì˜ ì†ŒìŠ¤ëŠ” 구조ì 으로 ë¬¸ì œê°€ 많았기 ë•Œë¬¸ì— ë§Žì€ ìˆ˜ì •ì´ í•„ìš”í–ˆìŠµë‹ˆë‹¤. ì´ì œ ë©€í‹°ì±„íŒ…ì„ ì™„ì„±í–ˆëŠ”ë°, í¬ì„±ì´ëŠ” ê³„ì •ì´ ì ìš©ëœ ì±„íŒ…ì„ ë§Œë“¤ì—ˆêµ°ìš”.. 멘붕 * ë‚œ 그냥 ì´ê±¸ 너네가 만들었다는거 ìžì²´ì—ì„œ 멘붕.. -[김태진] == ì˜ë¬¸ì == í”„ë¡œê·¸ëž¨ì„ ìž‘ì„±í•˜ë©´ì„œ ë“¤ì—ˆë˜ ì˜ë¬¸ì ì€ Pthread_joinì— ê´€í•œ 것입니다. 서버쪽ì—ì„œ ì“°ë ˆë“œë¥¼ ì“°ë©´ì„œ Joinì„ ì–´ë””ë‹¤ê°€ ë†”ì•¼í• ì§€ë¥¼ ëª¨ë¥´ê² ì–´ì„œ 한번 ë¹¼ë†“ê³ í•´ë³´ë‹ˆê¹Œ í”„ë¡œê·¸ëž¨ì´ ìž˜ ìž‘ë™ì´ ë˜ì—ˆìŠµë‹ˆë‹¤.(ìš°ì—°ì˜ ì‚°ë¬¼ ã… ã… ) 하지만 joinì´ ì—†ìœ¼ë©´ ìžì›ì´ í•´ì œê°€ ë˜ì§€ 않으니 메모리 누수가 ìƒê¸¸ ê²ë‹ˆë‹¤. 그래서 ì €ëŠ” joinì„ ì‚¬ìš©í•˜ê³ ì‹¶ì€ë° 어떻게 í•´ì•¼í• ì§€ë¥¼ ëª¨ë¥´ê² ë„¤ìš”. * ì„œë²„ì˜ ê²½ìš° listenì„ í•˜ê¸°ìœ„í•˜ì—¬ while문으로 무한 루프를 ëŒê³ 있으므로 ì¡°ì¸ì´ ì—†ì–´ë„ ìŠ¤ë ˆë“œê°€ ì¤‘ê°„ì— ì£½ì§€ì•ŠìŠµë‹ˆë‹¤. ê·¸ë¦¬ê³ mainì´ returnì„ í•˜ì—¬ 프로세스가 종료ë 경우 지ì‹ìŠ¤ë ˆë“œë„ ëª¨ë‘ ì¢…ë£Œë˜ë¯€ë¡œ main 함수 실행 ë„ì¤‘ì— ì¢…ë£Œí•´ì•¼í•˜ëŠ” 경우 ì´ì™¸ì—는 ë”°ë¡œ 처리를 하지 ì•Šì•„ë„ë©ë‹ˆë‹¤. ì°¸ê³ íŽ˜ì´ì§€- http://www.google.co.kr/url?sa=t&source=web&cd=5&ved=0CEkQFjAE&url=http%3A%2F%2F211.221.225.175%2F~comsys%2FNP_PDF%2Fchapter9.pdf&ei=B1B6T-XQLsaNiAfp7ozmAg&usg=AFQjCNGSvHjDhJuPzKXNM753wAi0WINORQ == ë¬¸ì œì == 소스가 ì •ë¦¬ê°€ 안ë˜ì„œ ì§€ì €ë¶„í•©ë‹ˆë‹¤. == 서버 == {{{ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/socket.h> #include<pthread.h> #define SIZE 1024 #define N 40 int client_socket[N+5], check[N+5], server_socket; int client_addr_size, flag = 0; char buff_snd[SIZE + 5], buff_rcv[SIZE + 5]; void *rcv(void *data){ int i; int temp = (int *)data; while(1){ if(recv(client_socket[temp], buff_rcv, SIZE, 0) <= 0)continue; else{ if(strcmp(buff_rcv, "exit") == 0){ printf("ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤.\n"); break; } printf( "receive: %s\n", buff_rcv); sprintf( buff_snd, "%d : %s", strlen( buff_rcv), buff_rcv); for(i = 1; i<=N; i++){ if(check[i])send(client_socket[i], buff_snd, strlen(buff_snd)+1, 0); } } } close(client_socket[temp]); client_socket[temp] = check[temp] = 0; } int main(void){ int option = 1; pthread_t pthread[N+5]; struct sockaddr_in server_addr, client_addr; int i; server_socket = socket(PF_INET, SOCK_STREAM, 0); setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); if (-1 == server_socket) { printf( "server socket ìƒì„± 실패"); exit( 1) ; } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(4000); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr))){ printf( "bind() 실행 ì—러\n"); exit( 1); } while(1){ if(listen(server_socket, 5) == -1){ printf( "대기ìƒíƒœ 모드 ì„¤ì • 실패\n"); exit( 1); } for(i = 1; i<=N; i++){ if(!check[i]){ client_addr_size = sizeof(client_addr); client_socket[i] = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_size); if(client_socket[i] == -1){ printf( "í´ë¼ì´ì–¸íŠ¸ ì—°ê²° ìˆ˜ë½ ì‹¤íŒ¨\n"); exit( 1); } check[i] = 1; pthread_create(&pthread[i], NULL, rcv, (void *)i); //int status; //pthread_join(pthread[i], (void **)&status); break; } } } printf("ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤.\n"); close(server_socket); exit(1); return 0; } }}} == í´ë¼ì´ì–¸íŠ¸ == {{{ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <pthread.h> #define SIZE 1024 int flag1 = 0, flag2 = 0; char buff_snd[SIZE + 5], buff_rcv[SIZE + 5]; int client_socket; void* snd(void *data){ while(!flag1){ while(flag2); gets(buff_rcv); send(client_socket, buff_rcv, strlen(buff_rcv)+1, 0); if(strcmp(buff_rcv, "exit") == 0){ flag1 = 1; printf("ì±„íŒ…ì´ ì¢…ë£Œë˜ì—ˆìŠµë‹ˆë‹¤.\n"); pthread_exit((void *)NULL); } flag2 = 1; } } void *rcv(void *data){ int temp; while(!flag1){ if(recv(client_socket, buff_rcv, SIZE, 0) <= 0)continue; else{ printf( "receive: %s\n", buff_rcv); sprintf( buff_snd, "%d : %s", strlen( buff_rcv), buff_rcv); flag2 = 0; } } } int main( int argc, char **argv) { pthread_t pthread[2]; struct sockaddr_in server_addr; client_socket = socket( PF_INET, SOCK_STREAM, 0); if( -1 == client_socket) { printf( "socket ìƒì„± 실패\n"); exit( 1); } memset( &server_addr, 0, sizeof( server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons( 4000); server_addr.sin_addr.s_addr= inet_addr( "127.0.0.1"); if( -1 == connect( client_socket, (struct sockaddr*)&server_addr, sizeof( server_addr) ) ) { printf( "ì ‘ì† ì‹¤íŒ¨\n"); exit( 1); } pthread_create(&pthread[0], NULL, snd, (void *)NULL); pthread_create(&pthread[1], NULL, rcv, (void *)NULL); int status; pthread_join(pthread[0], (void**)&status); pthread_join(pthread[1], (void**)&status); close(client_socket); exit(1); return 0; } }}}