Describe 김희성/리눅스멀티채팅 here
=서버=
#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 BUFF_SIZE 1024 int thread_num[25];//스레드 번호 (해당 스레드 활성화시 번호 값 + 1, 비활성화시 0) //ex) thread_num[스레드 번호]==스레드 번호+1 int client_socket_array[25];//클라이언트 소캣, 각 스레드 마다 자신의 번호에 해당하는 소캣 사용 //ex) 스레드가 사용 중인 소캣 == client_socket_array[스레드 번호] void* rutine(void* data)//data = &thread_num[스레드 번호] { int num; int client_socket; char buff_rcv[BUFF_SIZE+5],buff_snd[BUFF_SIZE+5]; int rcv; int i; num=*((int*)data); //사용자가 이해하기 쉽도록 스레드 번호에 +1 값을 쓰도록 한다. client_socket=client_socket_array[num-1]; //코드의 간결화를 위해 값을 복사한다. recv(client_socket, buff_rcv,BUFF_SIZE,0); printf("%s\n",buff_rcv); sprintf(buff_snd,"test\n"); send(client_socket, buff_snd, strlen(buff_snd)+1,0); printf("%dth client connected\n",num); //접속 검사 코드 while(1) { rcv=recv(client_socket,buff_rcv,BUFF_SIZE,0); if(rcv>0) { printf("received\n"); sprintf(buff_snd,"%dth client : %s",num,buff_rcv); for(i=0;i<20;i++) if(thread_num[i]) send(client_socket_array[i],buff_snd,strlen(buff_snd)+1,0); } else { break; } } printf("disconnected\n"); close(client_socket); thread_num[num-1]=0; client_socket_array[num-1]=0; //스레드가 비활성화 되었으므로 thread_num을 0으로 초기화한다. } int main() { int server_socket; pthread_t p_thread[25]; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int client_addr_size; int i; server_socket=socket(PF_INET, SOCK_STREAM, 0); if(server_socket==-1) { printf("socket error\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=htonl(INADDR_ANY); if(-1==bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))) { printf("bind error\n"); exit(1); } printf("server started\n"); for(i=0;i<20;i++) thread_num[i]=0; while(1) { if(-1==listen(server_socket,5)) { printf("listen error\n"); exit(1); } for(i=0;i<20;i++) { if(!thread_num[i]) { client_addr_size= sizeof(client_addr); client_socket_array[i] = accept(server_socket, (struct sockaddr*)&client_addr,&client_addr_size); thread_num[i]=i+1; memset(&p_thread[i],0,sizeof(p_thread[i])); pthread_create(&p_thread[i],NULL,rutine,(void *)&thread_num[i]); break; } } if(i==20) printf("error : Too many clients connected"); } close(server_socket); return 0; }
=클라이언트=
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<pthread.h> #define BUFF_SIZE 1024 void gotoxy(int x,int y) { printf("\033[%d;%df",y,x); //터미널 출력 위치 변경 함수, y값이 화면 길이보다 크면 화면 길이로 처리된다.(버그의 원인) fflush(stdout); } int client_socket; int check; void* rcv_thread(void *data) { int i; char buff_rcv[BUFF_SIZE+5]; int rcv; while(1) { rcv=recv(client_socket, buff_rcv, BUFF_SIZE, 0); if(rcv>0) { while(check==1); check=2; for(i=0;i<rcv;) { gotoxy(0,100);//gotoxy의 특징을 이용하여 화면을 한칸 올린다. printf("\n"); gotoxy(0,14); printf(" "); gotoxy(0,14); printf("%s",&buff_rcv[i]); i+=strlen(&buff_rcv[i])+1; } } else { printf("disconnected\n"); break; } gotoxy(0,15); printf("write message to send : "); gotoxy(25,15); check=0; } } void* snd_thread(void *data) { char buff_snd[BUFF_SIZE+5]; while(1) { while(check==2); check=1; gotoxy(0,15); printf("write message to send : "); gotoxy(25,15); check=0; fgets(buff_snd,BUFF_SIZE,stdin); check=0; if(send(client_socket, buff_snd, strlen(buff_snd)+1,0)<=0) { printf("disconnected\n"); break; } } } int main() { struct sockaddr_in server_addr; char buff_snd[BUFF_SIZE+5]; char buff_rcv[BUFF_SIZE+5]; int rcv; int i; pthread_t p_thread[2]; client_socket=socket(PF_INET, SOCK_STREAM, 0); if(client_socket==-1) { printf("socket error\n"); return 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("connect error\n"); return 1; } sprintf(buff_snd,"test\n"); send(client_socket, buff_snd, strlen(buff_snd)+1,0); recv(client_socket, buff_rcv,BUFF_SIZE,0); printf("%s\n",buff_rcv); printf("connecting succesed\n"); //* memset(&p_thread[0],0,sizeof(p_thread[0])); pthread_create(&p_thread[0],NULL,rcv_thread,(void *)NULL); memset(&p_thread[1],0,sizeof(p_thread[1])); pthread_create(&p_thread[1],NULL,snd_thread,(void *)NULL); pthread_join(p_thread[0],(void**)&rcv); pthread_join(p_thread[1],(void**)&rcv); //*/ /* while(1) { printf("write message to send : "); fgets(buff_snd,BUFF_SIZE,stdin); if(send(client_socket, buff_snd, strlen(buff_snd)+1,0)<0) { printf("disconnected\n"); break; } printf("sended\n\n"); while(1) { rcv=recv(client_socket, buff_rcv, BUFF_SIZE, 0); if(rcv>0) { for(i=0;i<rcv;) { printf("%s",&buff_rcv[i]); i+=strlen(&buff_rcv[i])+1; } break; } else { printf("disconnected\n"); break; } } if(rcv<=0) break; } //*/ close(client_socket); return 0; }