#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <errno.h>
#include <ctype.h>
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
#define OPEN_MAX 1024
int main()
{
int i,j,maxi,listenfd,connfd,sockfd;
int nready; /* 接收poll的返回值,记录满足监听事件的fd个数 */
ssize_t n;
char buf[MAXLINE], str[INET_ADDRSTRLEN];
socklen_t clielen;
struct pollfd client[OPEN_MAX];
struct sockaddr_in clieaddr, servaddr;
listenfd=Socket(AF_INET, SOCK_STREAM, 0);
int opt=1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
Listen(listenfd,128);
client[0].fd=listenfd; /* 要监听的第一个文件描述符 存入client[0] */
client[0].events=POLLIN; /* listenfd监听普通读事件 */
for(i=1;i<OPEN_MAX;i++); /* 用-1初始化client[]里剩下的元素 */
client[i].fd=-1;
maxi=0; /* maxi 保存有效元素的最大下标 */
for(;;)
{
nready=poll(client,maxi+1,-1); /*阻塞监听是否有客户端连接请求*/
if(client[0].revents & POLLIN)
{
clielen=sizeof(clieaddr);
connfd=Accept(listenfd, (struct sockaddr *)&clieaddr, &clielen);
printf("received from %s at port %d \n",
inet_ntop(AF_INET, &clieaddr.sin_addr,str,sizeof(str)),
ntohs(clieaddr.sin_port));
for(i=1;i<OPEN_MAX;i++)
{
if(client[i].fd < 0)
{
client[i].fd=connfd;
break;
}
}
if(i==OPEN_MAX)
perr_exit("too many clients");
client[i].events = POLLIN;
if(i > maxi)
maxi=i;
printf("nready=%d\n",nready);
if(--nready==0)
continue;
printf("nready=%d\n",nready);
}
for(i=1;i<=maxi;i++)
{
if((sockfd=client[i].fd) <0)
continue;
if(client[i].revents & POLLIN)
{
if((n=read(sockfd, buf, MAXLINE)) <0)
{
if(errno== ECONNRESET)
{
printf("client[%d] aborted connection\n",i);
close(sockfd);
client[i].fd=-1;
}
else
perr_exit("read error");
}
else if(n == 0)
{
printf("client[%d] closed connection \n",i);
close(sockfd);
client[i].fd=-1;
}
else
{
for(j=0; j< n; j++)
buf[j]=toupper(buf[j]);
sleep(2);
write(sockfd,buf,n);
}
if(--nready == 0)
break;
}
}
}
close(listenfd);
return 0;
}
C-socket编-poll()模型
最新推荐文章于 2024-07-21 19:29:22 发布