epoll实现并发服务器代码
#include <stdio.h>
#include <sys/stat.h>
#include <sys/sypes.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#define ERR_MSG(msg)do{\
fprintf(stderr,"line=%d\n",__LINE__);\
perror(msg);}while(0)
#define IP "192.168.8.61" //本机IP,ifconfig
#define PORT 6666
int main(int argc, const char *argv[])
{
//创建套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd <0)
{
ERR_MSG("socket");
return -1;
}
printf("sfd= %d\n",sfd);
//允许端口快速重用
int reuse = 1;
if(setsocket(sfd,SQL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) <0)
{
ERR_MSG("setsockopt");
return -1;
}
printf("允许端口快速重用成功!\n");
//填充地址信息结构体
//真实的地址信息结构体根据地址族制定 AF_INET:man 7 IP
struct sockaddr_in sin;
sin.sin_family =AF_INET; //必须填AF_INET;
sin.sin_port =htons(PORT); //端口号,1024~49151
sin.sin_addr.s_addr = inet_addr(IP); //本机IP,ifconfig
//将IP和端口绑定在套接字上
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success! line = %d\n",__LINE__);
//将套接字设置为被动监听状态,监听是否有客户端连接成功
if(listen(sfd,128) < 0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success! line = %d\n",__LINE__);
int ret,i;
struct epoll_event event;
struct epoll_event events[10];
char buf[128]="";
ssize_t res = 0;
//创建一个新的epoll
int epfd = epoll_create(1);
if(epfd < 0)
{
printf("epoll_create failed!\n");
exit(1);
}
//将要监听的事件文件描述符添加到epoll中
event.events = EPOLLIN;
event.data.fd = 0;
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,0,&event);
if(ret)
{
printf("epoll_ctl failed!\n");
exit(-1);
}
event.events = EPOLLIN;
event.data.fd = sfd;
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&event);
if(ret)
{
printf("epoll_ctl failed!\n");
exit(-1);
}
//循环监听
while(1)
{
ret = epoll_wait(epfd,events,10,-1);
if(ret<0)
{
printf("epoll_wait failed!\n");
exit(-1);
}
for(i=0;i<ret;i++)
{
if((events[i].events & EPOLLIN) && (events[i].data.fd == 0))
{
bzero(buf,sizeof(buf));
printf("出发键盘输入事件:");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1] = '\0';
if(send(sfd,buf,sizeof(buf),0) <0)
{
ERR_MSG("send");
return -1;
}
printf("发送成功!\n");
}
if((events[i].events & EPOLLIN) && (events[i].data.fd == sfd))
{
bzero(buf,sizeof(buf));
res = recv(sfd,buf,sizeof(buf),0);
if(res < )
{
ERR_MSG("recv");
return -1;
}
else if(0==res)
{
printf("sfd = %d 服务器下线",sfd);
break;
}
printf("sfd = %d : %s ,line = %d\n"sfd,buf,__LINE__);
}
}
}
close(sfd);
return 0;
}