U E D R , A S I H C RSS

권영기/채팅프로그램 (rev. 1.7)

권영기/채팅프로그램

Describe 권영기/채팅프로그램 here

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;
}
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:28:46
Processing time 0.0147 sec