Home IT Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ Linux Network Programming --epoll model Detailed principles and examples     - Nginx Keepalived Nginx monitoring scripts (Server)

- Increase ssh security service under Linux (Linux)

- How to use OpenVPN and PrivacyIDEA build two-factor authentication for remote access (Server)

- Oracle lag () and lpad () function (Database)

- Linux character device - a simple character device model (Linux)

- Linux prohibit non-WHEEL user su command Detail (Linux)

- The script Linux command (Linux)

- Linux find command to find files (Linux)

- Linux system file directory structure Introduction (Linux)

- Linux System Getting Started Tutorial: mounted directly in Linux LVM partition (Linux)

- Use nice, cpulimit and cgroups limit cpu usage (Linux)

- NaSC using simple mathematical operations on Ubuntu and Elementary OS (Linux)

- Android media library of analysis: MediaProvider (Programming)

- Linux tar compressed exclude a folder (Linux)

- To install the Oracle 10.2.0.1.0 process notes on Oracle Linux 4u4 (Database)

- Oracle query start with connect by tree (Database)

- Oracle 10g in the unique and index problems (Database)

- Apache Kafka: the next generation of distributed messaging system (Server)

- Linux hybrid character device (Linux)

- XenServer virtual machines installed in dual-card configuration (Server)

 
         
  Linux Network Programming --epoll model Detailed principles and examples
     
  Add Date : 2018-11-21      
         
       
         
  1. Introduction
Linux I / O multiplexing in more TCP network server in use, that is, the more use the select function. Linux 2.6 kernel, there are new ways to improve the network I / O performance, that epoll.
What epoll that? According to the manual say that man is made to handle large quantities handle and improved poll. To use epoll system only requires the following three function calls: epoll_create (2), epoll_ctl (2), epoll_wait (2).

2.select defect model
(1) in the Linux kernel, select the used FD_SET is limited
There is a kernel parameter __FD_SETSIZE define the number of handles each FD_SET: #define __FD_SETSIZE 1024. That is, if you want to handle 1025 simultaneous detection readable state is impossible to achieve with select; or simultaneous detection of 1025 handle writable state is impossible.
(2) is implemented in the kernel select polling method
Each test will traverse all FD_SET the handle, select the execution time is obviously a function of the ratio between the number of FD_SET the handle, the more you want to select the number of handles that is detected will be more time-consuming

Defect 3.Windows IOCP model
windows complete the ports of AIO, in fact, except for internal use thread pool to achieve the final result is IO has a thread pool, your application needs a thread pool. In fact, a lot of documents have already pointed out that the price caused by the thread context-switch brings.

Advantages 4.EPOLL Model
(1) to support a large number of processes open socket descriptor (FD)
epoll not select the model restrictions, FD upper limit is the maximum it can support the number of open files, this number is generally much larger than supported by select 2048. Here is my little display on the PC:
pt @ Ubuntu: ~ $ cat / proc / sys / fs / file-max
6815744
So for the server, this number will be even greater.
(2) IO efficiency increases linearly with the number of FD decline
Another Achilles heel of traditional select / poll is when you have a large socket set, was delayed due to a network, so that at any one time only a part of the socket is "active", and select / poll each invocation linear scan all collection efficiency resulting in decreased linearly. But epoll not have this problem, it only would be "active" socket operation: This is because the kernel implementation epoll fd is based on each of the above callback function implementation. Thus, only "active" socket will take the initiative to call the callback function, the other socket idle state will not. In this regard, epoll achieve a "pseudo" AIO ", because this time the driving force in the os kernel. In some benchmark, if substantially all of the socket are active, such as a high-speed LAN environment, epoll no better than select / poll how much lower efficiency, but if the call epoll_ctl excessive use, efficiency slightly decreased. However, once the use of idle connections simulated WAN environment, then epoll efficiency is far above the select / poll up.
Messaging (3) using mmap accelerate kernel and user space
Whether select, poll or epoll kernel needs the FD notification message to the user space, how to avoid unnecessary memory copies becomes very important. In this regard, epoll by kernel to user space mmap same memory implementation.

Mode 5.EPOLL Model
(1) LT mode
LT: level triggered, which is the default operating mode, supports both block and no-block socket, in this mode, the kernel tells you whether a file descriptor is ready, and then you can perform the IO operation ready fd . If you do not make any operation, the kernel will continue to inform you, therefore, this mode programming errors more likely to be smaller. Traditional select / poll is representative of this model.
(2) ET mode
LT: edge-triggered, this is a high-speed mode, only supports no-block socket. In this mode, when the descriptor becomes ready never ready, the kernel via epoll tell you, then it will assume that you know the file descriptor is ready, and will not for that file descriptor is ready to send more notice until you do some of the operations that lead to the file descriptor is no longer a ready state (for example, you send, receive or accept the request, or the transmission and reception of data is less than a certain amount of time has led to a EWOULDBLOCK error). Note, however, if this has not fd for IO operations (which causes it to become again not ready), the kernel will not send more notifications (only once). But in the TCP protocol acceleration utility ET mode still needs more benchmark confirmation.

Use 6.EPOLL Model
Epoll use all functions are declared in the header file sys / epoll.h the following brief description of the use of data structures and functions:
(1) epoll_data, epoll_data_t, epoll_event
typedef union epoll_data {
void * ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} Epoll_data_t;

struct epoll_event {
__uint32_t events; / * Epoll events * /
epoll_data_t data; / * User data variable * /
};

Epoll_event structure is used for event registration and event of interest occurred return pending. events field epoll_event structure is interested in the event and the event is triggered, the possible values are:
EPOLLIN: indicates that the corresponding file descriptor can be read;
EPOLLOUT: indicates that the corresponding file descriptor can be written;
EPOLLPRI: indicates that the corresponding file descriptor has urgent data readable;
EPOLLERR: indicates that the corresponding file descriptor errors occur;
EPOLLHUP: indicates that the corresponding file descriptor is dropped;
EPOLLET: file descriptor indicates that the corresponding event has occurred;

Commonwealth epoll_data to save a file descriptor trigger event related data. For example, a client connects to the server, the server can be obtained by calling the accept function corresponding to the client socket file descriptor that can be assigned to this file descriptor fd epoll_data the field, so that the back of the read and write operations on the file descriptor .

(2) epoll_create
Function declaration: intepoll_create (intsize)
Function Description: This function generates a special epoll file descriptor, which is a parameter to specify the maximum range of the descriptor generated.

(3) epoll_ctl function
Function declaration: intepoll_ctl (int epfd, int op, int fd, struct epoll_event * event)
Function Description: This function is used to control an event on a file descriptor, you can register events, modify events, delete events.
epfd: epoll_create generated by the dedicated epoll file descriptor;
op: operation to be performed, the possible values EPOLL_CTL_ADD registration, EPOLL_CTL_MOD modify, EPOLL_CTL_DEL deleted;
fd: file descriptor associated;
event: a pointer pointing epoll_event;
Returns 0 if the call is successful, unsuccessful -1 is returned.

(4) epoll_wait function
Function declaration: int epoll_wait (int epfd, structepoll_event * events, int maxevents, int timeout)
Function Description: This function is for generating polling I / O event.
epfd: epoll_create generated by the dedicated epoll file descriptor;
epoll_event: return array for processing on behalf of the event;
maxevents: each able to handle the number of events;
timeout: Wait time-out value I / O events;
Returns the number of events occurred.

7 design ideas and templates
The maximum number of handles to create a first epoll handle by create_epoll (int maxfds), which maxfds your epoll supports. This function returns a handle to the new epoll, after all operations will be operated by the handle. After the run, remember to use close () to close out this create epoll handle.
Then in your main loop inside the network, call epoll_wait (int epfd, epoll_event events, int max_events, int timeout) to query all of the network interfaces to see which can be read, which one can write. The basic syntax is:
nfds = epoll_wait (kdpfd, events, maxevents, -1);
Kdpfd which is used to create a handle epoll_create after, events epoll_event * is a pointer to a function when epoll_wait after the success of the operation, events which will store all of the read and write events. max_events is the number of all socket handles current needs listening. The last parameter indicates a timeout timeout condition epoll_wait of 0 means return immediately; -1 is a function would have been to wait until the event returns; indicates to wait so long time, if the event has not been any positive integer, It will return. Under normal circumstances, if the main loop is single-threaded network, you can use -1 wait, so you can ensure that some efficiency, and if the main loop in the same thread, then 0 can be used to ensure the efficiency of the main loop. After epoll_wait return, you should go into a loop, so that through all events.
For epoll operation as simple as that, but a total of four API: epoll_create, epoll_ctl, epoll_wait and close. The following is an example of man.

struct epoll_event ev, * events;
for (;;)
{
  nfds = epoll_wait (kdpfd, events, maxevents, -1); // wait IO event
  for (n = 0; n   {
  // If the socket is the main event, then enter the new connection, we need to deal with the new connection.
      if (events [n] .data.fd == listener)
      {
        client = accept (listener, (struct sockaddr *) & local, & addrlen);
if (client <0)
        {
            perror ( "accept error");
            continue;
        }
        // New connection into non-blocking mode
        setnonblocking (client);
        ev.events = EPOLLIN | EPOLLET;
        // Note that the parameters EPOLLIN | EPOLLET does not set the listening socket write,
        // If there is a write operation, it will not return this time epoll event,
        // If you want to write but also to listen, it should be EPOLLIN | EPOLLOUT | EPOLLET.
        // And will also add new connections EPOLL monitor queue
        ev.data.fd = client;
        // Set up after the event, this new event by epoll_ctl
        if (epoll_ctl (kdpfd, EPOLL_CTL_ADD, client, & ev) <0)
        {
            // Added to the epoll listening queue, here with EPOLL_CTL_ADD
            // To add a new epoll event. Can be reduced by EPOLL_CTL_DEL
            // A epoll event, by EPOLL_CTL_MOD to change the way an event listener.
            fprintf (stderr, "epoll set insertion error: fd =% d" 0, client);
            return -1;
        }
      }
      else
      // If the socket is not the main event, then it is on behalf of a user socket events
      // Socket is used to handle things this user is, for example, read (fd, xxx) and the like, or some other treatment.
        do_use_fd (events [n] .data.fd);
  }
} Simple example 8 EPOLL Model
#include < iostream>
#include < sys / socket.h>
#include < sys / epoll.h>
#include < netinet / in.h>
#include < arpa / inet.h>
#include < fcntl.h>
#include < unistd.h>
#include < stdio.h>

#define MAXLINE 10
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5555
#define INFTIM 1000

void setnonblocking (int sock)
{
  int opts;
  opts = fcntl (sock, F_GETFL);
  if (opts <0)
  {
      perror ( "fcntl (sock, GETFL)");
      exit (1);
  }
  opts = opts | O_NONBLOCK;
  if (fcntl (sock, F_SETFL, opts) <0)
  {
      perror ( "fcntl (sock, SETFL, opts)");
      exit (1);
  }
}

int main ()
{
  int i, maxi, listenfd, connfd, sockfd, epfd, nfds;
  ssize_t n;
  char line [MAXLINE];
  socklen_t clilen;
  // Declare variables epoll_event structure, ev register for the event, events for event backhaul array to be processed
  struct epoll_event ev, events [20];
  // Generate maximum range for handling accept the special epoll file descriptor, designated to generate descriptors 256
  epfd = epoll_create (256);
  struct sockaddr_in clientaddr;
  struct sockaddr_in serveraddr;
  listenfd = socket (AF_INET, SOCK_STREAM, 0);

  setnonblocking (listenfd); // set the socket for listening to non-blocking mode
  ev.data.fd = listenfd; // set the event to be handled with the file descriptor associated
  ev.events = EPOLLIN | EPOLLET; // set the type of event to be processed
  epoll_ctl (epfd, EPOLL_CTL_ADD, listenfd, & ev); // register epoll event
  bzero (& serveraddr, sizeof (serveraddr));
  serveraddr.sin_family = AF_INET;
  char * local_addr = "200.200.200.204";
  inet_aton (local_addr, & (serveraddr.sin_addr));
  serveraddr.sin_port = htons (SERV_PORT); // or htons (SERV_PORT);
  bind (listenfd, (sockaddr *) & serveraddr, sizeof (serveraddr));
  listen (listenfd, LISTENQ);

  maxi = 0;
  for (;;)
  {
      nfds = epoll_wait (epfd, events, 20, 500); // epoll event waiting to happen
      for (i = 0; i       {
        if (events [i] .data.fd == listenfd) // listens for events
        {
            connfd = accept (listenfd, (sockaddr *) & clientaddr, & clilen);
            if (connfd <0)
            {
              perror ( "connfd <0");
              exit (1);
            }
            setnonblocking (connfd); // set the socket to non-blocking client
            char * str = inet_ntoa (clientaddr.sin_addr);
            std :: cout << "connect from" << str << std :: endl;
            ev.data.fd = connfd; // set the file descriptor for read operations
            ev.events = EPOLLIN | EPOLLET; // read event set for measured injection
            epoll_ctl (epfd, EPOLL_CTL_ADD, connfd, & ev);
            // Register event ev
        }
        else if (events [i] .events & EPOLLIN) // read event
        {
            if ((sockfd = events [i] .data.fd) <0)
            {
              continue;
            }
            if ((n = read (sockfd, line, MAXLINE)) <0) // here and IOCP different
            {
              if (errno == ECONNRESET)
              {
                  close (sockfd);
                  events [i] .data.fd = -1;
              }
              else
              {
                  std :: cout << "readline error" << std :: endl;
              }
            }
            else if (n == 0)
            {
              close (sockfd);
              events [i] .data.fd = -1;
            }
            ev.data.fd = sockfd; // set the file descriptor for write operations
            ev.events = EPOLLOUT | EPOLLET; // NOTE measure provided for a write event
            // Modify the sockfd event to be handled as EPOLLOUT
            epoll_ctl (epfd, EPOLL_CTL_MOD, sockfd, & ev);
        }
        else if (events [i] .events & EPOLLOUT) // write event
        {
            sockfd = events [i] .data.fd;
            write (sockfd, line, n);
            ev.data.fd = sockfd; // set the file descriptor for read operations
            ev.events = EPOLLIN | EPOLLET; // set the read operation for registering events
            // Modify events on sockfd to be treated as EPOLIN
            epoll_ctl (epfd, EPOLL_CTL_MOD, sockfd, & ev);
        }
      }
  }
} 9.epoll Advanced Thinking

9.1. The source of the problem
Recently EPOLL learning model, said the introduction EPOLL with Windows IOCP model comparison, said its advantage is to solve a lot of overhead IOCP model thread context switching, so it can be seen, EPOLL model does not require multiple threads, which can be single-threaded EPOLL processing logic. If the introduction of multi-threaded but will cause some problems. But EPOLL server model in the end can not use multi-threading technology, and if so, how to choose change, which became troubled by my question. Internet search a bit, so there are several voices:
(1) "or event-driven (eg epoll), or multi-threaded or multi-process, put a few together to use, feel more trouble.";
(2) "single-threaded use epoll, but can not play multi-core; multithreaded without epoll.";
(3) "Master Communication FD thread epoll all need to be monitored, there are events to multi-thread to handle";
(4) "Now with the epoll, then the thread should not see fd, but only saw a business is a request / response; epoll network data assembled into business data transferred to the thread business to deal with this. is often said that half of the semi-synchronous asynchronous. "
I was inclined to support (3), (4) in view of the above
EPOLLOUT only in the buffer is full, can not send, after a while children have the buffer space, it will trigger EPOLLOUT, and only trigger once. If your programming network IO little, a little while to write the data, usually epoll_wait will immediately trigger EPOLLOUT; if you do not call epoll, direct write socket, then the situation will depend on the socket buffer area is not enough. If the buffer is sufficient, then write successfully. If the buffer is insufficient, then depending on your socket is not blocked or blocking to the write completes or an error is returned. So EPOLLOUT event has great randomness, ET mode generally used only for EPOLLIN, rarely used in EPOLLOUT.
9.2. Specific practices
(1) the primary communication thread epoll all FD need to be monitored, and is responsible for monitoring listenfd connfd, where only listen EPOLLIN event, does not listen to EPOLLOUT event;
(2) Once the data has been received from the Client, will be configured into a message into the message queue;
(3) number of working threads to compete, remove the message from the message queue and processes it, and sends the results to the client. Sending client operation performed by the worker thread. Direct write. write to or after EAGAIN EWOULDBLOCK, continue the thread loop waiting queue buffer
Send function code is as follows:

bool send_data (int connfd, char * pbuffer, unsigned int & len, int flag)
{
  if ((connfd <0) || (0 == pbuffer))
  {
      return false;
  }

  int result = 0;
  int remain_size = (int) len;
  int send_size = 0;
  const char * p = pbuffer;

  time_t start_time = time (NULL);
  int time_out = 3;

  do
  {
      if (time (NULL)> start + time_out)
      {
        return false;
      }

      send_size = send (connfd, p, remain_size, flag);
      if (nSentSize <0)
      {
        if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR))
        {
            continue;
        }
        else
        {
            len - = remain_size;
            return false;
        }
      }

      p + = send_size;
      remain_size - = send_size;
  } While (remain_size> 0);

  return true;
} 10 epoll implement server and client example
Finally, we use C ++ to implement a simple client retroreflective, is used by the code file

net.h server.cpp client.cpp server: epoll implementation, were doing two things: 1. waiting for clients to link 2 receives data from the client and the retroreflective;

Client: select to achieve, to do two things: 1. waiting for keyboard input, 2 to send data to the server and the receiving server retroreflective data;

/ ***********
net.h
*********** /
#include < stdio.h>

#ifndef _NET_H
#define _NET_H

#include < iostream>
#include < vector>
#include < algorithm>

#include < stdio.h>
#include < sys / types.h>
#include < sys / epoll.h> // epoll ways file
#include < sys / socket.h>
#include < fcntl.h> // block and noblock

#include < stdlib.h>
#include < error.h>
#include < unistd.h>
#include < arpa / inet.h>
#include < netinet / in.h>
#include < string.h>
#include < signal.h>

using namespace std;


#define hand_error (msg) do {perror (msg); exit (EXIT_FAILURE);} while (0)
#endif


/ ***********
server.c
*********** /
#include "net.h"
#define MAX_EVENTS 10000

int setblock (int sock)
{
    int ret = fcntl (sock, F_SETFL, 0);
    if (ret <0)
        hand_error ( "setblock");
    return 0;
}
int setnoblock (int sock) // set non-blocking mode
{
    int ret = fcntl (sock, F_SETFL, O_NONBLOCK);
    if (ret <0)
        hand_error ( "setnoblock");
    return 0;
}

int main ()
{
    signal (SIGPIPE, SIG_IGN);
  int listenfd;
    listenfd = socket (AF_INET, SOCK_STREAM, 0); // create a socket stream
    if (listenfd <0)
        hand_error ( "socket_create");
    setnoblock (listenfd);
    int on = 1;
    if (setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, & on, sizeof (on)) <0)
        hand_error ( "setsockopt");

    struct sockaddr_in my_addr;
    memset (& my_addr, 0, sizeof (my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons (18000); // here is host sequeue
    my_addr.sin_addr.s_addr = inet_addr ( "127.0.0.1");

    if (bind (listenfd, (struct sockaddr *) & my_addr, sizeof (my_addr)) <0)
        hand_error ( "bind");

    int lisId = listen (listenfd, SOMAXCONN);
    if (lisId <0) // LISTEN
        hand_error ( "listen");

    struct sockaddr_in peer_addr; // to save client addr
    socklen_t peerlen;
    // Here are some initialization, all about the epoll.
    vector clients;
    int count = 0;
    int cli_sock = 0;
    int epfd = 0; // epoll file descriptor
    int ret_events; // epoll_wait () return value
  struct epoll_event ev_remov, ev, events [MAX_EVENTS]; // events to hold the event read from the kernel
    ev.events = EPOLLET | EPOLLIN; // edge triggered
    ev.data.fd = listenfd;

    epfd = epoll_create (MAX_EVENTS); // create epoll, epoll file descriptor return value
    // Epfd = epoll_create (EPOLL_CLOEXEC); // The new wording
    if (epfd <0)
        hand_error ( "epoll_create");
    int ret = epoll_ctl (epfd, EPOLL_CTL_ADD, listenfd, & ev); // add time
    if (ret <0)
        hand_error ( "epoll_ctl");


    while (1)
    {
        ret_events = epoll_wait (epfd, events, MAX_EVENTS, -1); // similar to select function, here is waiting for the arrival of the event.
        if (ret_events == -1)
        {
            cout << "ret_events =" << ret_events << endl;
            hand_error ( "epoll_wait");
        }

        if (ret_events == 0)
        {
            cout << "ret_events =" << ret_events << endl;
            continue;
        }

// Cout << "ret_events =" << ret_events << endl;
        for (int num = 0; num         {
            cout << "num =" << num << endl;
            cout << "events [num] .data.fd =" << events [num] .data.fd << endl;
            if (events [num] .data.fd == listenfd) // client connect
            {
                cout << "listen sucess and listenfd =" << listenfd << endl;
                cli_sock = accept (listenfd, (struct sockaddr *) & peer_addr, & peerlen);
                if (cli_sock <0)
                    hand_error ( "accept");
                cout << "count =" << count ++;
                printf ( "ip =% s, port =% d \ n", inet_ntoa (peer_addr.sin_addr), peer_addr.sin_port);
                clients.push_back (cli_sock);
                setnoblock (cli_sock); // set to non-blocking mode
                ev.data.fd = cli_sock; // new connection will also join the listen queue EPOLL
                ev.events = EPOLLIN | EPOLLET;
                if (epoll_ctl (epfd, EPOLL_CTL_ADD, cli_sock, & ev) <0)
                    hand_error ( "epoll_ctl");
            }

            else if (events [num] .events & EPOLLIN)
            {
                cli_sock = events [num] .data.fd;
                if (cli_sock <0)
                    hand_error ( "cli_sock");
                char recvbuf [1024];
                memset (recvbuf, 0, sizeof (recvbuf));
                int num = read (cli_sock, recvbuf, sizeof (recvbuf));
                if (num == -1)
                    hand_error ( "read have some problem:");
                if (num == 0) // stand of client have exit
                {
                    cout << "client have exit" << endl;
                    close (cli_sock);
                    ev_remov = events [num];
                    epoll_ctl (epfd, EPOLL_CTL_DEL, cli_sock, & ev_remov);
                    clients.erase (remove (clients.begin (), clients.end (), cli_sock), clients.end ());
                }
                fputs (recvbuf, stdout);
                write (cli_sock, recvbuf, strlen (recvbuf));
            }
        }
    }

    return 0;
}

/ ***********
client.c
*********** /

#include "net.h"

int main ()
{
    signal (SIGPIPE, SIG_IGN);
  int sock;
    sock = socket (AF_INET, SOCK_STREAM, 0); // create a socket stream
    if (sock <0)
        hand_error ( "socket_create");

    struct sockaddr_in my_addr;

    // Memset my_addr;
    memset (& my_addr, 0, sizeof (my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons (18000); // here is host sequeue
// My_addr.sin_addr.s_addr = htonl (INADDR_ANY);
    my_addr.sin_addr.s_addr = inet_addr ( "127.0.0.1");

    int conn = connect (sock, (struct sockaddr *) & my_addr, sizeof (my_addr));
    if (conn! = 0)
        hand_error ( "connect");

    char recvbuf [1024] = {0};
    char sendbuf [1024] = {0};
    fd_set rset;
    FD_ZERO (& rset);

    int nready = 0;
    int maxfd;
    int stdinof = fileno (stdin);
    if (stdinof> sock)
        maxfd = stdinof;
    else
        maxfd = sock;
    while (1)
    {
        After // select return the original to be detected, but still did not ready word to describe cleared up. So before each call to select what should be re-set to be detected descriptor
        FD_SET (sock, & rset);
        FD_SET (stdinof, & rset);
        nready = select (maxfd + 1, & rset, NULL, NULL, NULL);
        cout << "nready =" << nready << "" << "maxfd =" << maxfd << endl;
        if (nready == -1)
            break;
        else if (nready == 0)
            continue;
        else
        {
            if (FD_ISSET (sock, & rset)) // detect whether the sock has been set rset inside.
            {
                int ret = read (sock, recvbuf, sizeof (recvbuf)); // read data
                if (ret == -1)
                    hand_error ( "read");
                else if (ret == 0)
                {
                    cout << "sever have close" << endl;
                    close (sock);
                    break;
                }
                else
                {
                    fputs (recvbuf, stdout); // output data
                    memset (recvbuf, 0, strlen (recvbuf));
                }
            }

            if (FD_ISSET (stdinof, & rset)) // detect whether the stdin file descriptor in the set
            {
                if (fgets (sendbuf, sizeof (sendbuf), stdin)! = NULL)
                {
                    int num = write (sock, sendbuf, strlen (sendbuf)); // write data
                    cout << "sent num =" << num << endl;
                    memset (sendbuf, 0, sizeof (sendbuf));
                }
            }
        }
    }
    return 0;
}
     
         
       
         
  More:      
 
- Linux Network Analysis Tcpdump Command Guide (Linux)
- C language programming entry - macro definitions and enum (Programming)
- FileZilla 3.10.1.1 install on Ubuntu 14.10 (Linux)
- sudo command scenario analysis (Linux)
- Ubuntu install snmp packets Unlinked OID in IPATM-IPMC-MIB: marsMIB (Linux)
- SolrCloud-5.2.1 cluster deployment and testing (Server)
- lolcat: an output terminal rainbow effects in the Linux command-line tool (Linux)
- Several back door and log tool under Linux (Linux)
- Redis configuration file interpretation (Database)
- Java implementation chain store binary tree (Programming)
- To update Python version under CentOS system (Linux)
- Getting Started with Linux system to learn: how to use tcpdump to capture TCP SYN, ACK and FIN packets (Linux)
- httpd-2.4 feature (Server)
- Android memory optimization of the disk cache (Linux)
- Those things packaged using Gradle to Android (Programming)
- Method under Linux GCC Compiler shared library function export control (Programming)
- echo command (Linux)
- Gentoo: !!! existing preserved libs problem (Linux)
- How to extend / remove swap partitions (Linux)
- When the master key encounter NULL (Database)
     
           
     
  CopyRight 2002-2016 newfreesoft.com, All Rights Reserved.