Describe 권영기/채팅프로그램 here === 2012/3/30 - 일대일 채팅 프로그램 만들기 === == 설명 == 서버에서도 메세지를 보낼 수 있고, 클라이언트에서도 메세지를 보낼 수 있습니다. exit를 치면 채팅을 종료합니다. == 문제점 == exit를 쳤을 때, 종료가 제대로 되지 않는 것이 문제입니다. client에서 exit를 쳤을 때, "채팅이 종료되었습니다." 라는 메세지가 바로 뜨지 않습니다. server에서 아무거나 입력하면 그제서야 client에서 "채팅이 종료되었습니다."가 출력됩니다. 그리고나서 server는 채팅 종료직전에 받았던 메세지를 무한히 출력합니다. server에서 exit를 쳤을 때, "채팅이 종료되었습니다." 라는 메세지가 바로 뜨지 않습니다. client에서 아무거나 입력하면 그제서야 server에서 "채팅이 종료되었습니다."가 출력됩니다. 그리고나서 client는 채팅 종료직전에 받았던 메세지를 무한히 출력합니다. 무한 루프에 관한 문제는 해결되었습니다. - 2012. 4. 3 == 서버 == {{{ #include #include #include #include #include #include #include #include #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 #include #include #include #include #include #include #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; } }}}