#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <poll.h>
#define IP "127.0.0.1"
#define PORT 20000
#define CLIENT_SIZE 1024
#define BUFF_SIZE 1024
int main()
{
int listenfd,connfd,sockfd;//listenfd用来accept新的连接, connfd作为accept的返回值,sockfd临时变量
struct sockaddr_in servaddr,clieaddr;//服务器地址和客户端地址
socklen_t clieaddrlen=sizeof(clieaddr);//客户端地址长度
int ret;//临时变量
struct pollfd client[CLIENT_SIZE];//poll函数使用的结构体数组
int i,j,maxi;
int nready;
char buff[BUFF_SIZE];//字符缓存区
char clientip[64];//存放客户端ip
int num;
listenfd=socket(PF_INET,SOCK_STREAM,0);//创建tcp套接字
if(listenfd<0)
{
perror("socket error");
exit(1);
}
//初始化服务器地址
memset(&servaddr,'\0',sizeof(servaddr));
servaddr.sin_family= AF_INET;
servaddr.sin_port=htons(PORT);
inet_pton(AF_INET,IP,&servaddr.sin_addr);
ret=bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));//绑定服务器地址
if(ret<0)
{
perror("bind error");
exit(1);
}
ret=listen(listenfd,128);//监听新的连接
if(ret<0)
{
perror("listen error");
exit(1);
}
for(i=0;i<CLIENT_SIZE;i++)//初始化client结构体
{
client[i].fd=-1;
}
//将listenfd赋值给client[0]
client[0].fd=listenfd;
client[0].events=POLLIN;//读事件
maxi=0;//始终指向client数组中最大的元素
while(1)
{
nready = poll(client,maxi+1,-1);//使用poll函数将套接字的状态监听交给内核
if(client[0].revents & POLLIN)//有新的连接请求
{
memset(&clieaddr,'\0',sizeof(clieaddr));
connfd = accept(listenfd,(struct sockaddr *)&clieaddr,&clieaddrlen);
printf("An new connection was accepted. IP = %s, PORT = %d\n",
inet_ntop(AF_INET,&clieaddr.sin_addr,clientip,sizeof(buff)),
ntohs(clieaddr.sin_port));
for(i=0;i<CLIENT_SIZE;i++)
{
if(client[i].fd==-1)//将新的套接字赋值给client数组,并进行监听
{
client[i].fd=connfd;
client[i].events=POLLIN;
if(maxi<i)
{
maxi=i;
}
break;
}
}
if(i==CLIENT_SIZE)//连接数超过了限制,关闭该连接
{
printf("too many clients, this connection will not be established.\n");
close(connfd);
}
if(--nready==0)//判断是否还有读事件满足
{
continue;
}
}
for(i=1;i<=maxi;i++)//逐个寻找满足读事件的各个套接字
{
if((sockfd=client[i].fd)<0)
{
continue;
}
if(client[i].revents & POLLIN)
{
num = recv(sockfd,buff,sizeof(buff),0);
if(num<0)
{
printf("recv error\n");
}
else if(num==0)
{
close(sockfd);
client[i].fd=-1;
printf("An client disconnected.\n");
}
else
{
for(j=0;j<num;j++)
{
buff[j]=toupper(buff[j]);
}
send(sockfd,buff,num,0);
}
if(--nready==0)
{
break;
}
}
}
}
}
运行效果:
[zlf@rhel5 day20181226]$ ./server
An new connection was accepted. IP = 127.0.0.1, PORT = 50031
An new connection was accepted. IP = 127.0.0.1, PORT = 50032
An client disconnected.
An new connection was accepted. IP = 127.0.0.1, PORT = 50033
An new connection was accepted. IP = 127.0.0.1, PORT = 50034
An client disconnected.
An client disconnected.
An client disconnected.