Last active
August 29, 2015 14:22
-
-
Save pineoc/88243648b5c35f71ee7c to your computer and use it in GitHub Desktop.
week14 network programming, select echo server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
pineoc, 2015-06-01 | |
week 14 network programming | |
select server | |
server code | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <arpa/inet.h> | |
#include <sys/socket.h> | |
#include <sys/select.h> | |
#include <sys/time.h> | |
#define BUF_SIZE 100 | |
void error_handling(char* msg); | |
void send_msg(char* msg,int len); | |
void handle_clnt(void* arg); | |
int main(int argc,char* argv[]) | |
{ | |
int serv_sock,clnt_sock; | |
struct sockaddr_in serv_addr,clnt_addr; | |
socklen_t addr_size; | |
int str_len; | |
struct timeval timeout; | |
fd_set reads,cpy_reads; | |
int fd_max,fd_num,i; | |
char buf[BUF_SIZE]; | |
int clnt_socks[100]; | |
int clnt_cnt=0; | |
if(argc!=2) | |
{ | |
printf("Usage error"); | |
exit(1); | |
} | |
serv_sock = socket(PF_INET,SOCK_STREAM,0); | |
memset(&serv_addr,0,sizeof(serv_addr)); | |
serv_addr.sin_family = AF_INET; | |
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); | |
serv_addr.sin_port = htons(atoi(argv[1])); | |
if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1) | |
error_handling("bind() err"); | |
if(listen(serv_sock,5)==-1) | |
error_handling("listen err"); | |
FD_ZERO(&reads); | |
FD_SET(serv_sock,&reads); | |
fd_max=serv_sock; | |
while(1) | |
{ | |
cpy_reads=reads; | |
timeout.tv_sec=5; | |
timeout.tv_usec=5000; | |
if((fd_num=select(fd_max+1,&cpy_reads,0,0,&timeout))==-1) | |
break; | |
if(fd_num==0) | |
continue; | |
for(i=0;i<fd_max+1;i++) | |
{ | |
if(FD_ISSET(i,&cpy_reads)) | |
{ | |
if(i==serv_sock) | |
{ | |
addr_size=sizeof(clnt_addr); | |
clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&addr_size); | |
clnt_socks[clnt_cnt++] = clnt_sock; | |
FD_SET(clnt_sock,&reads); | |
} | |
if(fd_max<clnt_sock) | |
fd_max=clnt_sock; | |
printf("connected client ip: %s, port:%d\n",inet_ntoa(clnt_addr.sin_addr),ntohs(clnt_addr.sin_port)); | |
} | |
else | |
{ | |
str_len=read(i,buf,BUF_SIZE); | |
if(str_len==0) | |
{ | |
FD_CLR(i,&reads); | |
//close(i); | |
handle_clnt((void*)&i); | |
printf("Closed client : %d\n",i); | |
} | |
else | |
{ | |
send_msg(buf,str_len); | |
} | |
} | |
} | |
} | |
close(serv_sock); | |
return 0; | |
} | |
void send_msg(char* msg,int len) | |
{ | |
int i; | |
for(i=0;i<clnt_cnt;i++) | |
{ | |
write(clnt_socks[clnt_cnt],msg,len); | |
} | |
} | |
void handle_clnt(void* arg) | |
{ | |
int i=0; | |
int clnt_sock=*((int*)arg); | |
int str_len=0; | |
char msg[BUF_SIZE]; | |
for(i=0;i<clnt_cnt;i++) | |
{ | |
if(clnt_sock==clnt_socks[i]) | |
{ | |
while(i++<clnt_cnt-1) | |
clnt_socks[i]=clnt_socks[i+1]; | |
break; | |
} | |
} | |
clnt_cnt--; | |
close(clnt_sock); | |
return NULL; | |
} | |
void error_handling(char* msg) | |
{ | |
fputs(msg,stderr); | |
fputc('\n',stderr); | |
exit(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment