Home > OS >  On Linux ET non-blocking mode under the correct closing of the connection problem
On Linux ET non-blocking mode under the correct closing of the connection problem

Time:11-08

scene description:
Server itself is the default for the FD LT block mode, a new connection, the client's FD set to non-blocking ET model, circular calls read, read 3 bytes each time, set the EAGAIN error handling, a return to the mistakes epoll_wait () continue to monitor,
Client connection interval after 5 seconds, every time send 10 bytes of data, the close loop three times after call/shutdown close the connection, set the SIGINT signal capture, received a CTRL + c key combination signals, also calls the close/shutdown close connections,

server
 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

# define PORT 8888
# define MAX_CONNECT 10
# define IN_ET_MODE EPOLLIN | EPOLLET
# define OUT_ET_MODE EPOLLOUT | EPOLLET

# define sys_err (ret, STR) \
Do \
{\
If (ret==1) \
{\
Perror (STR); \
exit(-1); \
} \
} while (0)

Int main (int arg c, char * const argv [])
{
Int SFD, CFD, epfd, ret, rdlen, I, EventNum;
Char buf [BUFSIZ]={0};
Char STR [INET_ADDRSTRLEN]={0};
Socklen_t socklen=sizeof (struct sockaddr_in);
Struct sockaddr_in SRV, cli;
Struct epoll_event evt, evts [MAX_CONNECT];
Memset (& amp; The SRV, 0, sizeof (SRV));
Memset (& amp; Cli, 0, sizeof (cli));
Memset (& amp; Evt, 0, sizeof (evt));
Memset (& amp; Evts, 0, sizeof (evts));

SFD=socket (AF_INET SOCK_STREAM, 0).
Sys_err (SFD, "socket");

//1. Create epoll_event handle, handle contains red HeiShu root node
Epfd=epoll_create (10);
Sys_err (epfd, "epoll_create");

//2. The SFD added to the red-black tree
Evt. Events=EPOLLIN;
Evt. Data. Fd=SFD;
Ret=epoll_ctl (epfd, EPOLL_CTL_ADD, SFD, & amp; Evt);
Epoll_ctl sys_err (ret, "");

//port multiplexing
Int opt=1;
Ret=setsockopt (SFD, SOL_SOCKET, SO_REUSEADDR, & amp; Opt, sizeof (opt));
Sys_err (ret, setsockopt "");

The SRV. Sin_family=AF_INET;
The SRV. Sin_port=htons (PORT);
The SRV. Sin_addr. S_addr=htonl (INADDR_ANY);
Ret=bind (SFD, (struct sockaddr *) & amp; The SRV, socklen);
Sys_err (ret, "bind");

Ret=listen (SFD, 128);
Sys_err (ret, "listen");

While (1)
{
Printf (" epoll_wait () to start listening to events \ n ");
EventNum=epoll_wait (epfd, evts, MAX_CONNECT, 1);
Sys_err (EventNum, "epoll_wait");

For (I=0; I & lt; EventNum; I++)
{

If (evts [I]. Data. Fd==SFD)//connection request
{
Printf (" % d has a connection request events \ n ", EventNum);
CFD=accept (SFD, (struct sockaddr *) & amp; Cli, & amp; Socklen);
Sys_err (CFD, "accept");
Printf (" % d client [u] % s: % connected \ n ",
CFD,
Inet_ntop (AF_INET, & amp; Cli. Sin_addr. S_addr, STR, sizeof (STR)),
Ntohs (cli) sin_port));
//non-blocking
Int flag=an FCNTL (CFD, F_GETFL);
Flag |=O_NONBLOCK;
An FCNTL (CFD, F_SETFL, flag);
//added to handle epoll_event
Evt. Events=EPOLLIN | EPOLLET;
Evt. Data. Fd=CFD;
Ret=epoll_ctl (epfd, EPOLL_CTL_ADD, CFD, & amp; Evt);
Epoll_ctl sys_err (ret, "");
}
The else//data request
{
Printf (" there is a data request event % d \ n ", EventNum);
Int sockfd=evts [I]. Data. Fd;
//printf (" % d client data requests: \ n ", sockfd);
While (1)
{
Memset (buf, 0, sizeof (buf));
Rdlen=read (sockfd, buf, 3);
//printf (" read return % d \ n ", rdlen);
If (rdlen & lt; 0)
{
If (errno==EAGAIN | | errno==EWOULDBLOCK)
{
Printf (" [EAGAIN] errno=% d, return % d \ n ", errno, rdlen);
break;
}
The else
{
Perror (" read ");
exit(-1);
}
}
Else if (rdlen & gt; 0)
{
Printf (" \ n [RECV] % s, % d ", buf, rdlen);
Int j;
For (j=0; J & lt; Rdlen; + + j)
Buf [j]=toupper (buf [j]);
Write (sockfd, buf, rdlen);
}
The else
{
Ret=epoll_ctl (epfd, EPOLL_CTL_DEL, sockfd, NULL);
Epoll_ctl sys_err (ret, "");
Close (sockfd);
Printf (" the client disconnected % d \ n ", sockfd);
break;
}
}
}
}
}

return 0;
}



client
 
#include
#include
#include
#include
#include
#include
#include

# define PORT 8888
# define sys_err (ret, STR) \
Do \
{\
If (ret==1) \
{\
Perror (STR); \
exit(-1); \
} \
} while (0)

Int CFD;

Void sigproc (int signo)
{
Printf (" CTRL + C signal, disconnect \ n ");
Close (CFD);
//shutdown (CFD, SHUT_RDWR);
exit(-1);
}
Int main (int arg c, char * const argv [])
{
Char buf [BUFSIZ]={" aaaaaaaaaa "};
Struct sockaddr_in SRV.
Memset (& amp; The SRV, 0, sizeof (SRV));

Signal (SIGINT, sigproc);

CFD=socket (AF_INET SOCK_STREAM, 0).

The SRV. Sin_family=AF_INET;
The SRV. Sin_port=htons (PORT);
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related