使用select
服务端
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#include <list>
#include <iostream>
#include <string.h>
#include<arpa/inet.h>
#define gPort 6000
using namespace std;
list<int> ClientSock;
void setClientFd(fd_set *rd)
{
for(list<int>::iterator i=ClientSock.begin(); i!=ClientSock.end(); ++i) {
FD_SET(*i, rd);
}
}
int main()
{
int sock, newsock, addrlen, MaxFd;
int sl;
struct sockaddr_in SerAddr, ClientAddr;
char Buf[1024];
fd_set rd, wd;
int val;
sock = socket(AF_INET, SOCK_STREAM, 0);
SerAddr.sin_family = AF_INET;
SerAddr.sin_port = htos(gPort);
SerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
val = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(val));
bind(sock, (struct sockaddr *)&SerAddr, sizeof(SerAddr));
listen(sock, 5);
addrlen = sizeof(struct sockaddr_in);
MaxFd = sock+1;
while(1)
{
FD_ZERO(&rd);
FD_SET(sock, &rd);
setClientFd(&rd);
sl = select(MaxFd, &rd, NULL, NULL, NULL);
if(sl>0) {
if(FD_ISSET(sock, &rd)) {
newsock= accept(sock, (struct sockaddr *)&ClientAddr, (socklen_t*)&addrlen);
if(newsock >= MaxFd) {
MaxFd = newsock+1;
}
cout<<"accept one connecton"<<endl;
cout<<"addr:"<< inet_ntoa(ClientAddr.sin_addr) <<"port:"<< ntohs(ClientAddr.sin_port) << endl;
ClientSock.push_back(newsock);
}
for(list<int>::iterator i=ClientSock.begin(); i!=ClientSock.end();) {
if(FD_ISSET(*i, &rd)) {
memset(Buf, 0, sizeof(Buf));
sl = recv(*i, Buf, sizeof(Buf), 0);
cout<<"recv: "<< Buf <<endl;
send(*i, "recv done", 9, 0);
if(memcmp(Buf, "close", 5) == 0) {
close(*i);
i = ClientSock.erase(i);
} else {
++i;
}
} else {
++i;
}
}
}
}
close(sock);
return 0;
}
客户端
#include <stdio.h>
#include <sys/socket.h>
//#include <sys/types.h>
//#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#define gSerAddr "127.0.0.1"
#define gSerPort 6000
#define STDIN 0
int main()
{
int sock, sl, MaxFd;
struct sockaddr_in SerAddr;
char Buf[1024];
fd_set rd, wd;
sock = socket(AF_INET, SOCK_STREAM, 0);
SerAddr.sin_family = AF_INET;
SerAddr.sin_port = htons(gSerPort);
SerAddr.sin_addr.s_addr = inet_addr(gSerAddr);
sl = connect(sock, &SerAddr, sizeof(SerAddr));
if(sl<0) {
perror("connect err\r\n");
return -1;
}
MaxFd = (sock>STDIN ? sock+1 : STDIN+1);
while(1) {
FD_ZERO(&rd);
//FD_ZERO(&wd);
FD_SET(sock, &rd);
FD_SET(STDIN, &rd);
sl = select(MaxFd, &rd, NULL, NULL, NULL);
if(sl>0) {
if(FD_ISSET(sock,&rd)) {
memset(Buf, 0, sizeof(Buf));
sl = recv(sock, Buf, sizeof(Buf), 0);
printf("recv:%d %s \n", sl, Buf);
}
if(FD_ISSET(STDIN, &rd)) {
sl = read(STDIN, Buf, sizeof(Buf));
send(sock, Buf, sl, 0);
if(memcmp(Buf, "close", 5)==0) {
close(sock);
break;
}
}
}
}
return 0;
}
使用POLL
服务端
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#include <list>
#include <iostream>
#include <string.h>
#include <arpa/inet.h>
#include <poll.h>
#include <vector>
#define gPort 6000
using namespace std;
int main()
{
int sock, newsock, addrlen;
int sl;
struct sockaddr_in SerAddr, ClientAddr;
char Buf[1024];
vector<struct pollfd> pfd;
struct pollfd nfd;
int val;
sock = socket(AF_INET, SOCK_STREAM, 0);
SerAddr.sin_family = AF_INET;
SerAddr.sin_port = htons(gPort);
SerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
val = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(val));
bind(sock, (struct sockaddr *)&SerAddr, sizeof(SerAddr));
listen(sock, 5);
addrlen = sizeof(struct sockaddr_in);
nfd.fd = sock;
nfd.events = POLLIN | POLLPRI;
pfd.push_back(nfd);
while(1)
{
sl = poll(&pfd[0], pfd.size(), -1);
if(sl>0) {
if((pfd[0].revents & POLLIN) || (pfd[0].revents & POLLPRI)) {
newsock= accept(sock, (struct sockaddr *)&ClientAddr, (socklen_t*)&addrlen);
cout<<"accept one connecton"<<endl;
cout<<"addr:"<< inet_ntoa(ClientAddr.sin_addr) <<"port:"<< ntohs(ClientAddr.sin_port) << endl;
nfd.fd = newsock;
nfd.events = POLLIN | POLLPRI;
pfd.push_back(nfd);
}
for(vector<struct pollfd>::iterator i=pfd.begin()+1; i!=pfd.end();) {
if((i->revents & POLLIN) || (i->revents & POLLPRI)) {
memset(Buf, 0, sizeof(Buf));
sl = recv(i->fd, Buf, sizeof(Buf), 0);
cout<<"recv: "<< Buf <<endl;
send(i->fd, "recv done", 9, 0);
if(memcmp(Buf, "close", 5) == 0) {
close(i->fd);
i = pfd.erase(i);
} else {
++i;
}
} else {
++i;
}
}
} else {
cout<<"poll wrong"<<endl;
}
}
close(sock);
return 0;
}
客户端
#include <stdio.h>
#include <sys/socket.h>
//#include <sys/types.h>
//#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <poll.h>
#include <unistd.h>
#define gSerAddr "127.0.0.1"
#define gSerPort 6000
int main()
{
int sock, sl;
struct sockaddr_in SerAddr;
char Buf[1024];
struct pollfd pfd[2];
sock = socket(AF_INET, SOCK_STREAM, 0);
SerAddr.sin_family = AF_INET;
SerAddr.sin_port = htons(gSerPort);
SerAddr.sin_addr.s_addr = inet_addr(gSerAddr);
sl = connect(sock, &SerAddr, sizeof(SerAddr));
if(sl<0) {
perror("connect err\r\n");
return -1;
}
pfd[0].fd = sock;
pfd[0].events = POLLIN | POLLPRI;
pfd[1].fd = STDIN_FILENO;
pfd[1].events = POLLIN| POLLPRI;
while(1) {
sl = poll(pfd, 2, -1);
if(sl>0) {
if((pfd[0].events & POLLIN) || (pfd[0].events & POLLPRI) ) {
memset(Buf, 0, sizeof(Buf));
sl = recv(sock, Buf, sizeof(Buf), 0);
printf("recv:%d %s \n", sl, Buf);
}
if((pfd[1].events & POLLIN) || (pfd[1].events & POLLPRI) ) {
sl = read(STDIN_FILENO, Buf, sizeof(Buf));
send(sock, Buf, sl, 0);
if(memcmp(Buf, "close", 5)==0) {
close(sock);
break;
}
}
}
}
return 0;
}
使用EPOLL
服务端
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#include <list>
#include <iostream>
#include <string.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#define gPort 6000
using namespace std;
const int EvtNum = 100;
int main()
{
int sock, newsock, addrlen;
int sl, ret;
struct sockaddr_in SerAddr, ClientAddr;
char Buf[1024];
int efd;
int val;
struct epoll_event evt;
struct epoll_event QueryEvt[EvtNum];
sock = socket(AF_INET, SOCK_STREAM, 0);
SerAddr.sin_family = AF_INET;
SerAddr.sin_port = htons(gPort);
SerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
val = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(val));
bind(sock, (struct sockaddr *)&SerAddr, sizeof(SerAddr));
listen(sock, 5);
addrlen = sizeof(struct sockaddr_in);
efd = epoll_create(10);
evt.events = EPOLLIN | EPOLLPRI;
evt.data.fd = sock;
epoll_ctl(efd, EPOLL_CTL_ADD, sock, &evt);
while(1)
{
sl = epoll_wait(efd, QueryEvt, EvtNum, 1000);
if(sl>0) {
ret = sl;
for(int i=0; i<ret; ++i) {
if((QueryEvt[i].events & EPOLLIN) || (QueryEvt[i].events & EPOLLPRI)) {
if(QueryEvt[i].data.fd == sock) {
newsock= accept(sock, (struct sockaddr *)&ClientAddr, (socklen_t*)&addrlen);
cout<<"accept one connecton"<<endl;
cout<<"addr:"<< inet_ntoa(ClientAddr.sin_addr) <<"port:"<< ntohs(ClientAddr.sin_port) << endl;
evt.data.fd = newsock;
evt.events = EPOLLIN | EPOLLPRI;
epoll_ctl(efd, EPOLL_CTL_ADD, newsock, &evt);
} else {
memset(Buf, 0, sizeof(Buf));
sl = recv(QueryEvt[i].data.fd, Buf, sizeof(Buf), 0);
if(sl<=0){
close(QueryEvt[i].data.fd);
epoll_ctl(efd, EPOLL_CTL_DEL, QueryEvt[i].data.fd, 0);
continue;
}
cout<<"recv: "<< Buf <<endl;
send(QueryEvt[i].data.fd, "recv done", 9, 0);
if(memcmp(Buf, "close", 5) == 0) {
close(QueryEvt[i].data.fd);
epoll_ctl(efd, EPOLL_CTL_DEL, QueryEvt[i].data.fd, 0);
}
}
}
}
} else if(sl==0) {
continue;
}else {
cout<<"epoll wrong"<<endl;
}
}
close(sock);
return 0;
}
客户端
#include <stdio.h>
#include <sys/socket.h>
//#include <sys/types.h>
//#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#define gSerAddr "127.0.0.1"
#define gSerPort 6000
int main()
{
int sock, sl, i;
struct sockaddr_in SerAddr;
char Buf[1024];
struct epoll_event QryEt[2];
sock = socket(AF_INET, SOCK_STREAM, 0);
SerAddr.sin_family = AF_INET;
SerAddr.sin_port = htons(gSerPort);
SerAddr.sin_addr.s_addr = inet_addr(gSerAddr);
sl = connect(sock, &SerAddr, sizeof(SerAddr));
if(sl<0) {
perror("connect err\r\n");
return -1;
}
int efd = epoll_create(2);
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLPRI;
ev.data.fd = sock;
epoll_ctl(efd, EPOLL_CTL_ADD, sock, &ev);
ev.data.fd = STDIN_FILENO;
epoll_ctl(efd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
while(1) {
sl = epoll_wait(efd, QryEt, 2, 1000);
if(sl>0) {
for(i=0; i<sl; ++i)
if((QryEt[i].events & EPOLLIN) || (QryEt[i].events & EPOLLPRI) ) {
if(QryEt[i].data.fd == sock) {
memset(Buf, 0, sizeof(Buf));
sl = recv(sock, Buf, sizeof(Buf), 0);
printf("recv:%d %s \n", sl, Buf);
} else if(QryEt[i].data.fd == STDIN_FILENO) {
sl = read(0, Buf, sizeof(Buf));
sl = send(sock, Buf, sl, 0);
printf("send %d \n", sl);
if(memcmp(Buf, "close", 5)==0) {
close(sock);
break;
}
}
}
} else if (sl==0) {
continue;
} else {
printf("epoll_wait wrong \n");
}
}
return 0;
}