Linux下网络编程-简易epoll服务器和客户端
简易epoll服务器水平模式:
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
int main(int argc, char *argv[])
{
int lfd = socket(AF_INET, SOCK_STREAM, 0);
if(lfd == -1)
{
perror("socket");
exit(0);
}
int opt=1;
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr;
addr.sin_port = htons(9527);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(lfd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
perror("bind");
exit(0);
}
if(listen(lfd, 100) == -1)
{
perror("listen");
exit(0);
}
int epfd=epoll_create(100);
if(epfd==-1)
{
perror("epoll_create");
exit(0);
}
struct epoll_event ev;
ev.events=EPOLLIN;
ev.data.fd=lfd;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &ev)==-1)
{
perror("epoll_ctl");
exit(0);
}
struct epoll_event evs[1024];
int size=sizeof(evs)/sizeof(epoll_event);
while(1)
{
int num=epoll_wait(epfd, evs, size, -1);
for(int i=0;i<num;i++)
{
int curfd=evs[i].data.fd;
if(curfd==lfd)
{
int cfd=accept(curfd, NULL, NULL);
ev.events=EPOLLIN;
ev.data.fd=cfd;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev)==-1)
{
perror("epoll_ctl_accept");
exit(0);
}
}
else
{
char buf[1024];
memset(buf,0,sizeof(buf));
int len=recv(curfd,buf,sizeof(buf),0);
if(len<=0)
{
printf("客户端已经断开了连接\n");
epoll_ctl(epfd, EPOLL_CTL_DEL, curfd, NULL);
close(curfd);
}
else
{
printf("客户端say: %s\n", buf);
memset(buf,0,sizeof(buf));
strcpy(buf,"ok");
send(curfd, buf, len, 0);
}
}
}
}
close(epfd);
close(lfd);
return 0;
}
简易epoll服务器边沿模式:
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
int main(int argc, char *argv[])
{
int lfd = socket(AF_INET, SOCK_STREAM, 0);
if(lfd == -1)
{
perror("socket");
exit(0);
}
int opt=1;
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr;
addr.sin_port = htons(9527);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(lfd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
perror("bind");
exit(0);
}
if(listen(lfd, 100) == -1)
{
perror("listen");
exit(0);
}
int epfd=epoll_create(100);
if(epfd==-1)
{
perror("epoll_create");
exit(0);
}
struct epoll_event ev;
ev.events=EPOLLIN|EPOLLET;
ev.data.fd=lfd;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &ev)==-1)
{
perror("epoll_ctl");
exit(0);
}
struct epoll_event evs[1024];
int size=sizeof(evs)/sizeof(epoll_event);
while(1)
{
int num=epoll_wait(epfd, evs, size, -1);
printf("==== num: %d\n", num);
for(int i=0;i<num;i++)
{
int curfd=evs[i].data.fd;
if(curfd==lfd)
{
int cfd=accept(curfd, NULL, NULL);
int flag=fcntl(cfd,F_GETFL);
flag|=O_NONBLOCK;
fcntl(cfd, F_SETFL,flag);
ev.events=EPOLLIN|EPOLLET;
ev.data.fd=cfd;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev)==-1)
{
perror("epoll_ctl_accept");
exit(0);
}
}
else
{
char buf[1024];
memset(buf,0,sizeof(buf));
while(1)
{
int len=recv(curfd,buf,sizeof(buf),0);
if(len==0)
{
printf("客户端已经断开了连接\n");
epoll_ctl(epfd, EPOLL_CTL_DEL, curfd, NULL);
close(curfd);
}
else if(len>0)
{
write(STDOUT_FILENO,buf,len);
memset(buf,0,sizeof(buf));
strcpy(buf,"ok");
send(curfd, buf, len, 0);
}
else
{
if(errno==EAGAIN)
{
printf("数据读完了...\n");
break;
}
else
{
perror("recv");
exit(0);
}
}
}
}
}
}
close(epfd);
close(lfd);
return 0;
}
简易客户端:
#include <netinet/in.h>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/select.h>
using namespace std;
int main()
{
int Client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Client == -1)
{
cout << "创建失败" << endl;
close(Client);
return -1;
}
const char* ip = "127.0.0.1";
unsigned short port=9527;
sockaddr_in addrServer;
addrServer.sin_addr.s_addr = inet_addr(ip);
addrServer.sin_port = htons(port);
addrServer.sin_family = AF_INET;
if (connect(Client, (sockaddr*)&addrServer, sizeof(addrServer))== -1)
{
cout << "连接失败" << endl;
close(Client);
return -1;
}
cout << "连接服务器成功" << endl;
char rec[1024];
char se[1024];
while(1)
{
memset(rec, 0, sizeof(rec));
memset(se, 0, sizeof(se));
scanf("%s", se);
if (strcmp(se, "quit") == 0 || strcmp(se, "exit") == 0)
break;
if (send(Client, se, sizeof(se), 0) < 0)
break;
cout << "发送:" << se << endl;
if (recv(Client, rec, sizeof(rec), 0) < 0)
break;
cout << "接收:" << rec << endl;
}
cout << "已与服务端断开连接" << endl;
close(Client);
return 0;
}