Encapsulation of Tcp_server and tcp_client functions in Linux network programming

Source: Internet
Author: User
Tags htons

The main purpose of this paper is to get the server sockets and client sockets, and make a simple package, using C language.

Tcp_server

Server-side FD acquisition is mainly divided into the following steps:

1. Create a socket, this step simply creates a socket with no attributes.

2. Bind the NIC and port, a host may have more than one network card, if we use inaddr_any, means that the later accepted TCP connection can be bound to any one NIC.

For example, the IP address of a host has two: 192.168.44.136, 10.1.1.4, assuming that the binding IP with Inaddr_any, the port is 9981, then when receiving a TCP connection, there may be 192.168.44.136:9981/ There are three possibilities of 10.1.1.4:9981/127.0.0.1:9981.

If we bind 192.168.44.136, then this FD receives the connection on this IP.

There is a special place, if the host is bound to 127.0.0.1, then the client must also be a process on this machine. Why )

3. Listen for Port listen, and actually start receiving TCP connections from this step. The second parameter of the Listen function represents the size of the TCP standby queue, which stores a connection that has completed three handshake but has not yet been accepted. If you set it to 3 and then open 4 client, but the server side does not accept, through Netstat–an | grep 9981, you can see that only three server-side connections are in the established state, and the remaining one is in the SYN_RCVD state.

So, many people mistakenly think that accept to complete three handshake, this is a wrong idea, three times handshake is done by the underlying protocol stack.

Then we need to use several socket options, followed by a dedicated article summarizing socket options:

1. Address multiplexing SO_REUSEADDR, code as follows:

// address re-use void set_reuseaddr (intint  optval) {    int01  0;     if sizeof 0 )        err_exit ("setsockopt so_reuseaddr");}

2. Port multiplexing So_reuseport, some machines do not support, so you need to judge

voidSet_reuseport (intSOCKFD,intoptval) {#ifdef So_reuseportintOn = (Optval! =0) ?1:0; if(SetSockOpt (SOCKFD, Sol_socket, So_reuseport, &on,sizeof(ON)) <0) Err_exit ("setsockopt So_reuseport");#elsefprintf (stderr,"So_reuseport is not supported.\n");#endif //So_reuseport}

3. Disable the Nagle algorithm to reduce LAN latency

// set whether the Nagle algorithm is available void set_tcpnodelay (intint  optval) {    int01 0 ;     if sizeof (ON)) = =-1)        err_exit ("setsockopt tcp_nodelay");}

4. Disabling the keepalive mechanism

void set_keepalive (intint  optval) {    int010 ;     if sizeof (ON)) = =-1)        err_exit ("setsockopt so_keepalive");}

We also need to add the domain name resolution function for our tcp_server, we can bind the hostname such as "localhost", not just the IP address, so we may use gethostbyname.

So the Tcp_server code is as follows:

intTcp_server (Const Char*host, uint16_t Port) {    //Handling Sigpipe SignalsHandle_sigpipe (); intLISTENFD = socket (pf_inet, Sock_stream,0); if(LISTENFD = =-1) Err_exit ("Socket"); Set_reuseaddr (LISTENFD,1); Set_reuseport (LISTENFD,1); Set_tcpnodelay (LISTENFD,0); Set_keepalive (LISTENFD,0);    SAI addr; memset (&AMP;ADDR,0,sizeofaddr); Addr.sin_family=af_inet; //addr.sin_addr.s_addr = inet_addr ("127.0.0.1");Addr.sin_port =htons (port); if(Host = =NULL) {addr.sin_addr.s_addr=Inaddr_any; }    Else    {        //int Inet_aton (const char *CP, struct in_addr *inp);        if(Inet_aton (host, &addr.sin_addr) = =0)        {            //DNS//struct hostent *gethostbyname (const char *name);            structHostent *HP =gethostbyname (host); if(HP = =NULL) Err_exit ("gethostbyname"); Addr.sin_addr= *(structin_addr*) hp->h_addr; }    }    if(Bind (LISTENFD, (sa*) &addr,sizeofaddr) = =-1) Err_exit ("Bind"); if(Listen (LISTENFD, somaxconn) = =-1) Err_exit ("Listen"); returnLISTENFD;}

Tcp_client

The client can also bind port, except that it is not required. The code is simple, as follows:

inttcp_client (uint16_t port) {intPEERFD = socket (pf_inet, Sock_stream,0); if(PEERFD = =-1) Err_exit ("Socket"); Set_reuseaddr (PEERFD,1); Set_reuseport (PEERFD,1); Set_keepalive (PEERFD,0); Set_tcpnodelay (PEERFD,0); //if port is 0, do not bind    if(Port = =0)        returnPEERFD;    SAI addr; memset (&AMP;ADDR,0,sizeofaddr); Addr.sin_family=af_inet; Addr.sin_port=htons (port); Addr.sin_addr.s_addr=inet_addr (Get_local_ip ()); if(Bind (PEERFD, (sa*) &addr,sizeof(addr)) == -1) Err_exit ("bind client"); returnpeerfd;}

The above need to get the IP address of the machine, the code is as follows:

Const Char*get_local_ip () {Static Charip[ -]; intSOCKFD; if(SOCKFD = socket (pf_inet, Sock_stream,0)) == -1) {Err_exit ("Socket"); }    structIfreq req; Bzero (&req,sizeof(structifreq)); strcpy (Req.ifr_name,"eth0"); if(IOCTL (SOCKFD, siocgifaddr, &req) = =-1) Err_exit ("IOCTL"); structsockaddr_in *host = (structsockaddr_in*) &req.ifr_addr; strcpy (IP, Inet_ntoa (host-sin_addr));        Close (SOCKFD); returnIP;}

Complete.

Encapsulation of Tcp_server and tcp_client functions in Linux network programming

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.