/*select_tcp.c*/
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/ioctl.h>
#define portnumber 3333
int main()
{
int server_sockfd,client_sockfd;
int server_len,client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
int result;
fd_set readfds,testfds;
/*为服务器创建并命名一个套接字*/
server_sockfd=socket(AF_INET,SOCK_STREAM,0);
server_address.sin_family=AF_INET;
server_address.sin_addr.s_addr=htonl(INADDR_ANY);
server_address.sin_port=htons(portnumber);
server_len=sizeof(server_address);
bind(server_sockfd,(struct sockaddr *)&server_address,server_len);
/*创建一个接连队列,初始化readfds以处理来自server_sockfd的输入*/
listen(server_sockfd,5);
FD_ZERO(&readfds);
FD_SET(server_sockfd,&readfds);
while(1)
{
char ch;
int fd;
int nread;
testfds=readfds;
printf("server waiting\n");
result=select(FD_SETSIZE,&testfds,(fd_set *)0,(fd_set *)0,(struct timeval *)0);
if(result<1)
{
perror("server");
exit(1);
}
/*一旦得知有活动发生,可以用FD_ISSET来依次检查每个描述符,以发现活动发生在哪个描述符上*/
for(fd=0;fd<FD_SETSIZE;fd++)
{
if(FD_ISSET(fd,&testfds))
/*如果活动发生在套接字server_sockfd上,肯定是一个新的连接请求,就可以把client_sockfd添加到描述符集合中*/
{
if(fd==server_sockfd)
{
client_len=sizeof(client_address);
client_sockfd=accept(server_sockfd,(struct sockaddr *)&client_address,&client_len);
FD_SET(client_sockfd,&readfds);
printf("adding client on fd %d\n",client_sockfd);
}
/*如果活动不是发生在服务器套接字上,那肯定是客户的活动*/
else
{
ioctl(fd,FIONREAD,&nread);
if(nread==0)
{
close(fd);
FD_CLR(fd,&readfds);
printf("removing client on fd %d\n",fd);
}
else
{
read(fd,&ch,1);
sleep(2);
printf("serveing client on fd %d\n",fd);
ch++;
write(fd,&ch,1);
}
}
}
}
}
}