epoll 实现实时聊天
服务器端:
#include <func.h>
int tcpInit(int *sFd,char* ip,char* port)
{
int socketFd;
socketFd=socket(AF_INET,SOCK_STREAM,0);
ERROR_CHECK(socketFd,-1,"socket");
int ret;
int reuse=1;
ret=setsockopt(socketFd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int));
ERROR_CHECK(ret,-1,"setsockopt");
struct sockaddr_in serAddr;
bzero(&serAddr,sizeof(serAddr));
serAddr.sin_family=AF_INET;
serAddr.sin_port=htons(atoi(port));
serAddr.sin_addr.s_addr=inet_addr(ip);
ret=bind(socketFd,(struct sockaddr*)&serAddr,sizeof(struct sockaddr));
ERROR_CHECK(ret,-1,"bind");
listen(socketFd,10);
*sFd=socketFd;
return 0;
}
void setNonBlock(int fd)
{
int status=fcntl(fd,F_GETFL);
status=status|O_NONBLOCK;
fcntl(fd,F_SETFL,status);
}
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,3);
int socketFd;
int ret;
ret=tcpInit(&socketFd,argv[1],argv[2]);
if(-1==ret)
{
return -1;
}
int newFd;
struct sockaddr_in clientAddr;
bzero(&clientAddr,sizeof(clientAddr));
socklen_t addrLen=sizeof(clientAddr);
newFd=accept(socketFd,(struct sockaddr*)&clientAddr,&addrLen);
ERROR_CHECK(newFd,-1,"accept");
printf("client ip=%s,client port=%d\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
char buf[6]={0};
int readyFdCount;
int epfd=epoll_create(1);
ERROR_CHECK(epfd,-1,"epoll_create");
struct epoll_event event,evs[2];
event.events=EPOLLIN;
event.data.fd=STDIN_FILENO;
//寮€濮嬬洃鎺ф爣鍑嗚緭鍏ョ殑璇讳簨浠?
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,&event);
ERROR_CHECK(ret,-1,"epoll_ctl");
setNonBlock(newFd);//璁剧疆涓洪潪闃诲
event.events=EPOLLIN|EPOLLET; //璁剧疆涓鸿竟娌胯Е鍙?
event.data.fd=newFd;
ret=epoll_ctl(epfd,EPOLL_CTL_ADD,newFd,&event);
ERROR_CHECK(ret,-1,"epoll_ctl");
int i;
while(1)
{
readyFdCount=epoll_wait(epfd,evs,2,-1);
for(i=0;i<readyFdCount;i++)
{
if(newFd==evs[i].data.fd)
{
while(1)
{
memset(buf,0,sizeof(buf));
ret=recv(newFd,buf,sizeof(buf)-1,0);//瀹㈡埛绔柇寮€锛宺ecv杩斿洖鍊间负闆讹紝鎻忚堪绗︿竴鑷村彲璇?
if(0==ret)
{
printf("byebye\n");
goto end;
}else if(-1==ret&&errno==EAGAIN)
{
printf("\n");
break;
}else{
printf("%s",buf);
}
}
}
if(STDIN_FILENO==evs[i].data.fd)
{
memset(buf,0,sizeof(buf));
read(STDIN_FILENO,buf,sizeof(buf)-1);
send(newFd,buf,strlen(buf)-1,0);
}
}
}
end:
close(newFd);
close(socketFd);
return 0;
}
客户端:
#include <func.h>
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,3);
int socketFd;
socketFd=socket(AF_INET,SOCK_STREAM,0);
ERROR_CHECK(socketFd,-1,"socket");
printf("socketFd=%d\n",socketFd);
struct sockaddr_in serAddr;
bzero(&serAddr,sizeof(serAddr));
serAddr.sin_family=AF_INET;
serAddr.sin_port=htons(atoi(argv[2]));
serAddr.sin_addr.s_addr=inet_addr(argv[1]);
int ret;
ret=connect(socketFd,(struct sockaddr*)&serAddr,sizeof(serAddr));
ERROR_CHECK(ret,-1,"connect");
char buf[128]={0};
fd_set rdset;
int readyFdCount;
while(1)
{
FD_ZERO(&rdset);
FD_SET(STDIN_FILENO,&rdset);//鏍囧噯杈撳叆娣诲姞鍒伴泦鍚堜腑
FD_SET(socketFd,&rdset);
readyFdCount=select(socketFd+1,&rdset,NULL,NULL,NULL);
if(readyFdCount>0)
{
if(FD_ISSET(socketFd,&rdset))
{
memset(buf,0,sizeof(buf));
ret=recv(socketFd,buf,sizeof(buf),0);
if(0==ret)
{
printf("byebye\n");
break;
}
printf("%s\n",buf);
}
if(FD_ISSET(STDIN_FILENO,&rdset))
{
memset(buf,0,sizeof(buf));
read(STDIN_FILENO,buf,sizeof(buf)-1);
send(socketFd,buf,strlen(buf)-1,0);
}
}
}
close(socketFd);
return 0;
}