Skip to content

Instantly share code, notes, and snippets.

@pineoc
Last active August 29, 2015 14:22
Show Gist options
  • Save pineoc/88243648b5c35f71ee7c to your computer and use it in GitHub Desktop.
Save pineoc/88243648b5c35f71ee7c to your computer and use it in GitHub Desktop.
week14 network programming, select echo server
/*
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