epoll
https://www.jianshu.com/p/718c24af400f
int r=0;
r=set_noblock(socket_);
if((r=connect(socket_, (struct sockaddr*)addr, sizeof(sockaddr_in_t))) <0){
int err = errno;
if(err == EISCONN)
return 1;//"already con";
else if(err != EINPROGRESS && err != EALREADY && err != EWOULDBLOCK && err)
return -1;//"con error";
}
else{
return 0;//"ok con";
}
fd_set readset, writeset, exceptionset;
struct timeval tval;
tval.tv_sec = 0;
tval.tv_usec = 20000;
//try now
for(int i=1; i<=times; ++i){
FD_ZERO(&readset);
FD_SET(socket_, &readset);
FD_ZERO(&writeset);
FD_SET(socket_, &writeset);
FD_ZERO(&exceptionset);
FD_SET(socket_, &exceptionset);
if((r=select(socket_+1, &readset, &writeset, &exceptionset, &tval)) < 0){
if(errno == EINTR)
continue;
else
return -2;//"select failed";
}
else if(r == 0){
//"time out";
continue;
}
else{
if(FD_ISSET(socket_, &exceptionset)){
if(i == times) return -4;//"exception";
else continue;
}
if( FD_ISSET(socket_, &writeset)){
if( FD_ISSET(socket_, &readset)){
if(i == times) return -8; //error
else continue;
}
int error = 0;
socklen_t len = sizeof(error);
int rc = getsockopt(socket_, SOL_SOCKET, SO_ERROR, (char *) &error, &len);
if(rc == -1 || error)
if(i == times) return -16;//"failed";
else continue;
else{
return 0;
break;
}
}
}
}
server
#include <sys/epoll.h>
#include <fcntl.h>
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero
#include <arpa/inet.h> // inet_ntoa
#define LISTENQ 20
#define MAXLINE 10000
#define SERV_PORT 6666
int main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in cliaddr, servaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
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, LISTENQ);
int addrSize = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr*) &cliaddr, &addrSize);
printf("connected from:%s, port:%d \n\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
close(listenfd); /* close listening socket */
int epollFd;
epollFd = epoll_create(256);
struct epoll_event ev,events[20];
ev.data.fd=connfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epollFd,EPOLL_CTL_ADD,connfd,&ev);
// stdin = 0
ev.data.fd=0;
ev.events=EPOLLIN;
epoll_ctl(epollFd,EPOLL_CTL_ADD,0,&ev);
char sendline[MAXLINE], recvline[MAXLINE];
while(1){
int nfds=epoll_wait(epollFd,events,20,0);
for (int i = 0; i < nfds; ++i){
if(events[i].data.fd==connfd){
int n = read(connfd, recvline, MAXLINE); // TODO: add n == 0
fputs(recvline, stdout);
}else if(events[i].data.fd==0){
fgets(sendline, MAXLINE, stdin);
send(connfd, sendline, strlen(sendline), 0);
}
}
}
close(connfd);
close(epollFd);
return 0;
}
client
#include <sys/epoll.h>
#include <fcntl.h>
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero
#include <arpa/inet.h> // inet_ntoa
#include <unistd.h>
#define SERV_PORT 6666
#define MAXLINE 10000
struct sockaddr_in servaddr, servaddr1;
int
main(int argc, char **argv)
{
int connfd;
if (argc != 2){
printf("usage: tcpcli <IPaddress>");
exit(0);
}
connfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
connect(connfd, (struct sockaddr*) &servaddr, sizeof(servaddr));
int epollFd;
epollFd = epoll_create(256);
struct epoll_event ev,events[20];
ev.data.fd=connfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epollFd,EPOLL_CTL_ADD,connfd,&ev);
// stdin = 0
ev.data.fd=0;
ev.events=EPOLLIN;
epoll_ctl(epollFd,EPOLL_CTL_ADD,0,&ev);
char sendline[MAXLINE], recvline[MAXLINE];
while(1){
int nfds=epoll_wait(epollFd,events,20,0);
for (int i = 0; i < nfds; ++i){
if(events[i].data.fd==connfd){
int n = read(connfd, recvline, MAXLINE);
fputs(recvline, stdout);
}else if(events[i].data.fd==0){
fgets(sendline, MAXLINE, stdin);
send(connfd, sendline, strlen(sendline), 0);
}
}
}
close(connfd);
close(epollFd);
return 0;
}