Advanced programming in Unix environment chapter16 network IPC: socket

chapter16 network IPC: socket

socket descriptor

To create a socket, call the socket function

/*
domain: Communication domain
type: socket type 
protocol: agreement
*/
int socket(int domain,int type,int protocol);   //If successful, the file (socket) descriptor is returned

Socket communication domain is divided into:

fielddescribe
AF_INETIPv4 Internet domain
AF_INET6IPv6 Internet domain
AF_UNIXUNIX domain
AF_UPSPECUnspecified

Socket types are divided into:

typedescribe
SOCK_DGRAMFixed length, connectionless and unreliable message transmission
SOCK_RAMDatagram interface of IP protocol
SOCK_SEQPACKETFixed length, orderly, reliable and connection oriented message transmission
SOCK_STREAMOrdered, reliable, bidirectional, connection oriented byte stream

For a datagram (SOCK_DGRAM) interface, no logical connection is required for communication between two peer processes. Only one message needs to be sent to the socket used by the peer process. Sock_stream requires a logical connection between the local socket and the socket of the communicating peer process before exchanging data.

SOCK_RAW socket provides a datagram interface for direct access to the following network layer (i.e. IP layer in Internet domain) When using this interface, the application is responsible for building its own protocol header because the transmission protocol (such as TCP and UDP) is bypassed. When creating a raw socket, super user privilege is required, which can prevent malicious reference programs from bypassing the built-in security mechanism to create messages.

Agreement types are divided into:

agreementdescribe
IPPROTO_IPIPv4 network protocol
IPPROTO_IPV6IPv6 network protocol
IPPROTO_ICMPInternet control message protocol
IPPROTO_RAWOriginal IP packet protocol
IPPROTO_TCPTransmission control protocol
IPPROTO_UDPUser datagram protocol

In AF_ Socket type sock in INET communication domain_ The default protocol of stream is transmission control protocol (TCP). In AF_ In socket domain, socket type_ The default protocol of Dgram is UDP.

Calling socket is similar to calling open. In both cases, file descriptors for I/O are available. When the file descriptor is no longer needed, close is called to close access to the file or socket and release the descriptor for reuse.

addressing

In the process of socket communication, the target communication process is determined by process identification. Process identification consists of two parts. One part is the network address of the computer, which can help identify the computer we want to communicate with on the network; The other part is the services represented by port numbers on the computer, which can help identify specific processes.

When communicating on different computers, the byte order needs to be considered. The byte order of different processors may be different. In Unix, the network protocol specifies the byte order (network byte order), so heterogeneous computer systems can exchange protocol information without being confused by the byte order.

TCP / IP protocol stack uses big endian byte order. TCP / IP addresses are represented by network byte order, so applications sometimes need to convert them between processor byte order and network byte order. (the correlation function is as follows)

// h represents the byte order of "host" and n represents the byte order of "network". l stands for "long" integer and s stands for "short" integer
uint32_t htonl(uint32_t host32);
uint16_t htons(uint16_t host16);
uint32_t ntohl(uint32_t netint32);
uint16_t ntohs(uint16_t netint16);

An address identifies the socket endpoint of a specific communication domain, and the address format is related to this specific communication domain. In order to enable different format addresses to be passed into socket function, the address will be forcibly converted into a general address structure sockaddr;

struct sockaddr{
    sa_family_t sa_family;      /*address family*/
    char        sa_data[];      /*variable-langth address*/
    //...
};

In Linux, the address is SOCKADDR_ Definition in

struct sockaddr_in{
    sa_family_t sin_family;     /*address family*/
    in_port_t   sin_port;       /*port number*/
    struct in6_addr sin6_addr;  /*IPv4 address*/
    unsigned char   sin_zero[8];/*filter*/
};

The definitions of addresses may be different in different systems. When used, they are forced into sockaddr structure and input into socket routine

For the server, it is necessary to associate a well-known address with a server socket that accepts the client's request, and use the bind function to associate the address and socket.

int bind(int sockfd,const struct sockaddr* addr,socklen_t len);

There are some restrictions on the addresses used:

  • On the computer where the process is running, the specified address must be valid; You cannot specify the address of another machine;
  • The address must match the format supported by the address family when creating the socket;
  • The port number in the address must not be less than 1024 unless the process has corresponding privileges (i.e. super user);
  • Generally, only one socket endpoint can be bound to a given address, although some protocols allow multiple binding;

Establish connection

To handle a connection oriented network service, a connection needs to be established between the process socket (server) requesting the service and the process socket (server) providing the service before exchanging data. Use the connect function to establish a connection.

int connect(int sockfd,const struct sockaddr* addr,socklen_t len);  //If successful, return 0; If there is an error, return - 1

In order for a connection request to succeed, the computer to be connected must be turned on and running, the server must be bound to an address to be connected with, and the waiting connection queue of the server must have enough space. Therefore, the application must be able to handle the errors returned by connect, which may be caused by some transient conditions.

//Exponential compensation reconnection algorithm
int connect_retry(int sockfd,const struct sockaddr* addr,socklen_t alen)
{
    int numsec;
    /*
    *   Try to connect with exponential backoff.
    */
    for(numsec=1;numsec<=MAXSLEEP;numsec<<=1){
        if(connect(sockfd,addr,alen)==0)
            return 0;
        if(numsec<=MAXSLEEP/2)
            sleep(numsec);
    }
    return -1;
}

The server calls the listen function to announce that it is willing to accept the connection request:

//The backlog provides a prompt indicating the number of outstanding connection requests that the system needs to queue up. The actual value is determined by the system.
int listen(int sockfd,int backlog);     //If successful, return 0; If there is an error, return - 1

Once the server calls listen, the socket used can accept the connection request. Use the accept function to obtain the connection request and establish the connection.

int accept(int sockfd,struct sockaddr* restrict addr,socklen_t *restrict len);  //If successful, return the file (socket) descriptor; If there is an error, return - 1

The file descriptor returned by the function accept is the socket descriptor, which is connected to the client calling connect. This new socket descriptor has the same socket type and address family as the original socket (sockfd). The original socket passed to accept is not associated with this connection, but remains available and accepts other connection requests.

data transmission

In socket communication, there are three functions for sending data and three functions for receiving data.

//send data
ssize_t send(int sockfd,const void* buf,size_t nbytes,int flags);
ssize_t sento(int sockfd,const void* buf,size_t nbytes,int flags,const struct sockaddr* destaddr,socklen_t destlen);        //Specify the destination address for sending
ssize_t sendmsg(int sockfd,const struct msghdr* msg,int flags);
//Accept data
ssize_t recv(int sockdf,void* buf,size_t nbytes,int flags);
ssize_t recvfrom(int sockfd,void* restrict buf,size_t len,int flags,struct sockaddr* restrict addr,socklen_t *restrict addrlen);    //Accept the data and get the sender's address
ssize_t recvmsg(int sockfd,struct msghdr* msg,int flags);

Out of band data

Out of band data is an optional function supported by some communication protocols. Compared with ordinary data, it allows higher priority data transmission. Out of band data is transmitted first, even if there is data in the transmission queue. TCP supports out of band data, but UDP does not.

TCP refers to out of band data as emergency data. TCP only supports one byte of emergency data, but allows emergency data to be transmitted outside the data stream of ordinary data transmission mechanism. If the signal generation is arranged through the socket, the SIGURG signal will be sent when the emergency data is accepted.

Keywords: Linux Unix network socket

Added by wholetthe15 on Wed, 09 Feb 2022 12:49:40 +0200