Network Programming Jo, Heeseung
Network 실습 네트워크프로그래밍 멀리떨어져있는호스트들이서로데이터를주고받을수있도록프로그램을구현하는것 파일과는달리데이터를주고받을대상이멀리떨어져있기때문에소프트웨어차원에서호스트들간에연결을해주는장치가필요 이러한기능을해주는장치로소켓이라는인터페이스를많이사용 소켓프로그래밍이란용어와네트워크프로그래밍이랑용어가같은의미로사용 Network 실습에서는 TCP/IP 소켓통신을이용하여 Server/Client 채팅프로그램을작성 2
Server/Client 채팅프로그램을작성 Server 채팅프로그램은 HBE-SM5-S4210에서실행 Client 채팅프로그램은리눅스에서실행 chat_server 채팅채팅서버서버 SMIII-SV210 SM5-S4210 chat_client chat_client chat_client 채팅클라이언트리눅스 (Ubuntu-8.04, fedora8,...) 3
Server 채팅프로그램 소스파일작성 - chat_server.c 를작성 root@ubuntu:/working/3.network/chatting/chat_server-arm# vi chat_server.c 001: #include <stdio.h> 002: #include <stdlib.h> 003: #include <unistd.h> 004: #include <string.h> 005: #include <arpa/inet.h> 006: #include <sys/types.h> 007: #include <sys/socket.h> 008: #include <netinet/in.h> 009: #include <pthread.h> 010: 011: #define BUFSIZE 100 4
012: 013: void * clnt_connection(void *arg); 014: void send_message(char * message, int len); 015: void error_handling(char *message); 016: 017: int clnt_number=0; 018: int clnt_socks[10]; 019: pthread_mutex_t mutx; 020: 021: int main(int argc, char **argv) 022: { 023: int serv_sock; 024: int clnt_sock; 025: int clnt_addr_size; 026: int option=1; 027: struct sockaddr_in serv_addr; 028: struct sockaddr_in clnt_addr; 029: pthread_t thread; 030: 031: printf("================================\n"); 032: printf("tcp/ip Chatting Program - Server\n"); 5
033: printf("================================\n\n"); 034: 035: if(argc!=2) { 036: printf("usage : %s <port>\n", argv[0]); 037: exit(1); 038: } 039: 040: if(pthread_mutex_init(&mutx, NULL)) 041: error_handling("mutex init error"); 042: 043: serv_sock=socket(pf_inet, SOCK_STREAM, 0); 044: if(serv_sock == -1) 045: error_handling("socket() error"); 046: 047: setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); 048: 049: memset(&serv_addr, 0, sizeof(serv_addr)); 050: serv_addr.sin_family=af_inet; 051: serv_addr.sin_addr.s_addr=htonl(inaddr_any); 052: serv_addr.sin_port=htons(atoi(argv[1])); 053: 6
054: if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1) 055: error_handling("bind() error"); 056: 057: if(listen(serv_sock, 5)==-1) 058: error_handling("listen() error"); 059: 060: while(1){ 061: clnt_addr_size=sizeof(clnt_addr); 062: clnt_sock=accept(serv_sock, (struct sockaddr*) &clnt_addr, &clnt_addr_size); 063: 064: pthread_mutex_lock(&mutx); 065: clnt_socks[clnt_number++]=clnt_sock; 066: pthread_mutex_unlock(&mutx); 067: 068: pthread_create(&thread, NULL, clnt_connection, (void*)clnt_sock); 069: printf(" IP : %s \n", inet_ntoa(clnt_addr.sin_addr)); 070: } 071: return 0; 072: } 7
073: 074: void * clnt_connection(void *arg) 075: { 076: int clnt_sock= (int)arg; 077: int str_len=0; 078: char message[bufsize]; 079: int i; 080: 081: while( (str_len=read(clnt_sock, message, sizeof(message)))!= 0) 082: send_message(message, str_len); 083: 084: pthread_mutex_lock(&mutx); 085: for(i=0; i<clnt_number; i++){ 086: if(clnt_sock == clnt_socks[i]){ 087: for( ; i<clnt_number-1; i++) 088: clnt_socks[i]=clnt_socks[i+1]; 089: break; 090: } 091: } 092: clnt_number--; 8
093: pthread_mutex_unlock(&mutx); 095: close(clnt_sock); 096: return 0; 097: } 099: void send_message(char * message, int len) 100: { 101: int i; 102: 103: message[len]=0; 104: fputs(message, stdout); 105: pthread_mutex_lock(&mutx); 106: for(i=0; i<clnt_number; i++) 107: write(clnt_socks[i], message, len); 108: pthread_mutex_unlock(&mutx); 109: bzero(message, sizeof(message)); 110: } 112: void error_handling(char *message) 113: { 114: fputs(message, stderr); 115: fputc('\n', stderr); 116: exit(1); 117: } 9
Makefile 작성 root@ubuntu:/working/3.network/chatting/chat_server-arm# vi Makefile CC= arm-linux-gcc APP=chat_server CFLAGS = -D_REENTRANT -lpthread OBJS=chat_server.o all: $(APP) $(APP): $(OBJS) $(CC) $(CFLAGS) -o $@ $^ clean: rm -f $(OBJS) $(APP) 10
컴파일 root@ubuntu:/working/3.network/chatting/chat_server-arm# make arm-linux-gcc -c -D_REENTRANT -lpthread -o chat_server.o chat_server.c arm-linux-gcc -D_REENTRANT -lpthread -o chat_server chat_server.o root@ubuntu:/working/3.network/chatting/chat_server-arm# ls Makefile chat_server chat_server.c chat_server.o 테스트 board 에전송후 board 에서실행 11
chat_server 를실행 [root@sm5s4210 ~]#./chat_server ================================ TCP/IP Chatting Program - Server ================================ Usage :./chat_server <port> [root@sm5s4210 ~]#./chat_server 9000 ================================ TCP/IP Chatting Program - Server ================================ 12
Client 채팅프로그램 HBE-SM5-S4210 에서실행한 Server 채팅프로그램에접속할 Client 채팅프로그램을리눅스 (Ubuntu-10.10) 용으로작성 소스파일작성 - chat_client.c 를작성 root@ubuntu:/working/3.network/chatting/chat_client-x86# vi chat_client.c 001: #include <stdio.h> 002: #include <stdlib.h> 003: #include <unistd.h> 004: #include <string.h> 005: #include <arpa/inet.h> 006: #include <sys/types.h> 13
007: #include <sys/socket.h> 008: #include <pthread.h> 009: 010: #define BUFSIZE 100 011: #define NAMESIZE 20 012: 013: void * send_message(void *arg); 014: void * recv_message(void *arg); 015: void error_handling(char *message); 016: 017: char name[namesize]="[default]"; 018: char message[bufsize]; 019: 020: int main(int argc, char **argv) 021: { 022: int sock; 023: struct sockaddr_in serv_addr; 024: pthread_t snd_thread, rcv_thread; 025: void * thread_result; 026: 027: printf("================================\n"); 028: printf("tcp/ip Chatting Program - Client\n"); 14
029: printf("================================\n\n"); 030: 031: if(argc!=4){ 032: printf("usage : %s <IP> <port> <name>\n", argv[0]); 033: exit(1); 034: } 035: 036: sprintf(name, "[%s]", argv[3]); 037: 038: sock=socket(pf_inet, SOCK_STREAM, 0); 039: if(sock==-1) 040: error_handling("socket() error"); 041: 042: memset(&serv_addr, 0, sizeof(serv_addr)); 043: serv_addr.sin_family=af_inet; 044: serv_addr.sin_addr.s_addr=inet_addr(argv[1]); 045: serv_addr.sin_port=htons(atoi(argv[2])); 046: 047: if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) 048: error_handling("connect() error"); 049: 15
050: pthread_create(&snd_thread, NULL, send_message, (void*)sock); 051: pthread_create(&rcv_thread, NULL, recv_message, (void*)sock); 052: 053: pthread_join(snd_thread, &thread_result); 054: pthread_join(rcv_thread, &thread_result); 055: 056: close(sock); 057: return 0; 058: } 059: 060: void * send_message(void *arg) 061: { 062: int sock = (int)arg; 063: char name_message[namesize+bufsize]; 064: while(1) { 065: fgets(message, BUFSIZE, stdin); 066: if(!strcmp(message,"q\n")) { 067: close(sock); 068: exit(0); 069: } 070: sprintf(name_message,"%s %s", name, message); 071: write(sock, name_message, strlen(name_message)); 16
072: } 073: } 074: 075: void * recv_message(void *arg) 076: { 077: int sock = (int)arg; 078: char name_message[namesize+bufsize]; 079: int str_len; 080: int f_read=1; 081: 082: while(f_read){ 083: str_len = read(sock, name_message, NAMESIZE+BUFSIZE-1); 084: if(str_len==-1) f_read=0; 085: else { 086: name_message[str_len]=0; 087: fputs(name_message, stdout); 088: } 089: } 090: } 091: 17
092: void error_handling(char *message) 093: { 094: fputs(message, stderr); 095: fputc('\n', stderr); 096: exit(1); 097: } 18
Makefile 작성 root@ubuntu:/working/3.network/chatting/chat_client-x86# vi Makefile CC= gcc APP=chat_client CFLAGS = -D_REENTRANT -lpthread OBJS=chat_client.o all: $(APP) $(APP): $(OBJS) $(CC) $(CFLAGS) -o $@ $^ clean: rm -f $(OBJS) $(APP) 19
컴파일 root@ubuntu:/working/3.network/chatting/chat_client-x86# make gcc -c -D_REENTRANT -lpthread -o chat_client.o chat_client.c gcc: -lpthread: linker input file unused because linking not done gcc -D_REENTRANT -lpthread -o chat_client chat_client.o root@ubuntu:/working/3.network/chatting/chat_client-x86# ls Makefile chat_client chat_client.c chat_client.o 21
chat_client 실행 생성된 chat_client 파일을리눅스에실행하여채팅서버에접속 root@ubuntu:/working/3.network/chatting/chat_client-x86#./chat_client ================================ TCP/IP Chatting Program - Client ================================ Usage :./chat_client <IP> <port> <name> root@ubuntu:/working/3.network/chatting/chat_client-x86#./chat_client 192.168.0.150 9000 park ================================ TCP/IP Chatting Program - Client ================================ 22