Socket Connection
Socket is a communication machine. With this mechanism, the development of the customer/server system can be carried out on both a local single machine and a network. The creation and use of sockets are different from those of pipelines, because sockets clearly differentiate customers from servers.
Socket connection:
First, the server application uses the system to call the socket to create a socket, which is a resource similar to the file descriptor allocated to the server process by the system and cannot be shared with other processes.
Next, the server process will name the socket. The name of a local socket is the file name in the Linux File System. For a network socket, its name is a service identifier related to the specific network connected by the customer. This identifier allows Linux to redirect a connection to a specific port number to a correct server process. We use bind to name the socket. Then the server process starts waiting for the customer to connect to the socket named. The system calls listen to create a queue and store incoming connections from customers. The server uses the system to call accept to accept the customer's connection.
When the server calls accept, it creates a new socket that is different from the original named socket. This socket is only used to communicate with this specific customer, while the named socket is retained to continue processing the connection from the customer.
The socket system-based client is simpler. The customer first calls the socket to create an unnamed socket, and then uses the named socket of the server as an address to call connect to establish a connection with the server.
Socket Properties
The characteristics of a socket are determined by three attributes: domain, type, and protocol. The socket also uses the address as its name. The address format varies with the domain. Each protocol can use one or more addresses to define the format.
Socket domain
Specifies the network medium used in socket communication. The most common socket field is AF_INET, which refers to the interconnected network. Its underlying protocol-the Internet Protocol has only one address family. It uses a specific method to specify the computer in the network, which is commonly referred to as the IP address.
Multiple services may be running on the server computer at the same time. You can use an IP port to specify a specific service on a networked machine. Inside the system, the port is identified by a unique 16-bit integer. outside the system, it must be determined by a combination of IP addresses and port numbers. As the end of the communication, the socket must be bound to a port before the communication starts.
The socket domain can also be AF_UNIX, which can be used even for sockets on a computer that is not connected to the Internet. The underlying protocol of this domain is the file input/output, and its address is the absolute path file name. Our server socket address is server_socket.
Socket Type
A socket domain may have multiple communication modes, and each communication mode has different features. AF_UNIX domain sockets do not have this problem because they provide a reliable two-way communication path.
The Internet Protocol provides two different services: stream and datagram.
Stream socket:
Stream sockets provide an ordered, reliable, and bidirectional byte stream connection. Therefore, you can ensure that the sent data is not lost, copied, or in disorder, and the errors that occur during this process are not displayed. The stream socket is specified by SOCK_STREAM, which is implemented through TCP/IP connection in the AF_INET domain. They are also the most common socket types in the AF_UNIX domain.
Datagram socket
The datagram socket specified by SOCK_DGRAM does not establish or maintain a connection. It limits the length of data packets that can be sent. A datagram is transmitted as a separate network message, which may be lost, copied, or unordered.
The datagram socket is implemented through UDP/IP connection in the AF_INET domain. It provides an unreliable service that is not needed. However, from the perspective of Ziyun, their overhead is relatively small because they do not need to maintain network connections. And because they don't have to spend time building them up, their speed is also fast. UDP stands for the datagram protocol.
SOCKET protocol
As long as the underlying transmission mechanism allows more than one protocol to provide the required socket type, you can select a specific protocol for the socket.
Create socket
The socket system creates a socket and returns a descriptor, which can be used to access the socket.
# Include <sys/types. h>
# Include <sys/socket. h>
Int socket (intdomain, int type, int protocol );
The created socket is an endpoint of a communication line. The domain parameter specifies the protocol family, the type parameter specifies the socket communication type, and the protocol parameter specifies the protocol used.
The most common sockets are AF_UNIX and AF_INET. The former is used to implement a local ring for UNIX file systems, and the latter is used for network sockets.
The value of type includes SOCK_STREAM and SOCK_DGRAM.
The protocols used for communication are generally determined by the socket type and socket domain, and usually do not need to be selected. Setting the protocol parameter to 0 indicates that the default protocol is used.
The socket system calls a descriptor.
Socket address
Each socket domain has its own format.
For the AF_UNIX domain socket, its address is described by the sockaddr_un structure. The result is defined in the sys/un. h header file.
Structsockrrd_un {
Sa_family_t sun_family;
Char sun_path [];
};
Here, sun_family specifies the address type, and sun_path is the file name to specify the socket address.
In the AF_INET domain, the socket address is specified by the socketaddr_in structure. This structure is defined in the file netinet/in. h and contains at least the following members:
Structsocket_in {
Short int sin_family;
Unsigned short int sin_port;
Struct in_addr sin_addr;
};
The IP address structure in_addr is defined
Struct in_addr {
Unigned long int s_addr;
};
The four bytes in the IP address constitute a 32-bit value. An AF_INET socket is completely determined by its domain, IP address, and port number.
Named socket
The server must name the socket to enable the socket created by a socket call to be used by other processes. In this way, the AF_UNIX socket is associated with the path name of a file system. AF_INET socket settlement is associated with an IP port.
# Include <sys/types. h>/* See NOTES */
# Include <sys/socket. h>
Int bind (intsockfd, const struct sockaddr * addr, socklen_t addrlen );
The bind System Call assigns the address in the addr parameter to the Untitled socket associated with the file descriptor. The length of the address structure is transmitted by the address_len parameter.
The bind Call needs to convert a specific address structure pointer to a generic type (struct sockaddr *).
If the bind Call is successful, 0 is returned. If the call fails,-1 is returned.
Create a socket queue
To accept incoming connections on a socket, the server program must create a queue to store unprocessed requests. Use the listen system call to implement this task.
# Include <sys/types. h>/* See NOTES */
# Include <sys/socket. h>
Int listen (int sockfd, int backlog );
In the socket queue, the number of connections waiting for processing cannot exceed the number of backlogs. The connection will be rejected later.
Accept connection
# Include <sys/types. h>/* See NOTES */
# Include <sys/socket. h>
Int accept (int sockfd, struct sockaddr * addr, socklen_t * addrlen );
Once a socket is created and named by the server program, it can be called by the accept system to wait for the client to establish a connection to the socket.
The accept system call is returned only when the customer tries to connect to the socket specified by the sockfd parameter. The customer here refers to the first unprocessed connection in the socket queue. The accept function creates a new socket to communicate with the customer and returns the descriptor of the new socket. The type of the new socket is the same as that of the server listening socket.
The socket must be named by the bind Call in advance, and a connection queue is assigned to the socket by the listen call. The address of the connected customer will be placed in the sockaddr structure pointed to by the address parameter.
The address_len parameter specifies the length of the customer structure. If the length of the customer address exceeds this value, it will be intercepted. Therefore, before calling accept, address_len must be set to the expected address length. When this call returns, address_len is set to the actual length of the client address structure.
If no unprocessed connections exist in the socket queue, accept will be blocked until a customer establishes a connection. You can set the O_NOBLOCK flag for the socket file descriptor to change this line and use the fcntl function.
Request connection
The customer connects to the server by establishing a connection between the Untitled socket and the server listening socket.
# Include <sys/types. h>
# Include <sys/socket. h>
Int connect (intsockfd, const struct sockaddr * addr, socklen_t addrlen );
The socket specified by the sockfd parameter is connected to the server socket specified by the addr parameter. The length of the structure to which the addr points is specified by the addrlen parameter.
Disable socket
You can use the close function to terminate the connection between the server and the client socket.
Host byte and network byte
In order for different computers to reach an agreement on the values of Multi-byte integers transmitted over the network, a network byte order is required. The customer and server must convert their internal integer representation to the network byte order before transmission. You can use the following functions to complete this task.
# Include <arpa/inet. h>
Uint32_t htonl (uint32_t hostlong );
Uint16_thtons (uint16_t hostshort );
Uint32_tntohl (uint32_t netlong );
Uint16_tntohs (uint16_t netshort );
Htonl indicates "host tonetwork, long ".
Network Information
You can call gethostent to find the specified host information.
# Include <netdb. h>
Struct hostent * gethostent (void );
Void sethostent (int stayopen );
Void endhostent (void );
Struct hostent {
Char * h_name;
Char ** h_aliases;
Inth_addrtype;
Inth_length;
Char ** h_addr_list ;};
Obtain the network name and network number from the interface:
# Include <netdb. h.
Struct netent * getnetbyaddr (uint32_t net, int type );
Struct netent * getnetbyname (const char * name );
Struct netent * getnetent (void );
Void setnetent (int stayopen );
Void endnetent (void );
Struct netent {
Char * n_name;
Char ** n_aliases;
Intn_addrtype;
Uint32_t n_net ;};
MAP Protocol names and protocol numbers using the following functions
# Include <netdb. h>
Struct protoent * getprotobyname (const char * name );
Struct protoent * getprotobynumber (intproto );
Struct protoent * getprotoent (void );
Void setprotoent (int stayopen );
Void endprotoent (void );
Struct protoent {
Char * p_name;
Char ** p_aliases;
Intp_proto ;};
Ing from a service name to a port number, service name
# Include <netdb. h>
Struct servent * getservbyname (const char * name, const char * proto );
Struct servent * getservbyport (int port, const char * proto );
Struct servent * getservent (void );
Void setervent (int stayopen );
Void endservent (void );
Struct servent {
Char * s_name;
Char ** s_aliases;
Ints_port;
Char * s_proto ;};
Maps a host name and service name to an address.
# Include <sys/socket. h>
# Include <netdb. h>
Int getaddrinfo (const char * restrict host, const char * restrict service, const struct addrinfo * restrict hint, structaddrinfo ** restrict res );
Void freeaddrinfo (struct addrinfo * ai );
Struct addrinfo {
Intai_flags;
Intai_family;
Intai_socktype;
Intai_protocol;
Socklen_t ai_addrlen;
Structsockaddr * ai_addr;
Char * ai_canonname;
Structaddrinfo * ai_next ;};
Gai_strerror converts the returned error code into an error message
# Include <netdb. h>
Const char * gai_strerror (int error );
Converts an address to a host or service name.
# Include <sys/socket. h>
# Include <netdb. h>
Int getnameinfo (const struct sockaddr * restrict addr, socklen_t alen, char * restrict host, socklen_t hostlen, char * restrict service, socklen_t servlen, unsigned int flags );
Data Transmission
Send data:
# Include <sys/types. h>
# Include <sys/socket. h>
Ssize_t send (int sockfd, const void * buf, size_t len, int flags );
Ssize_t sendto (int sockfd, const void * buf, size_t len, int flags,
Const struct sockaddr * dest_addr, socklen_t addrlen );
Ssize_t sendmsg (int sockfd, const struct msghdr * msg, int flags );
Struct msghdr {
Void * msg_name;/* optional address */
Socklen_t msg_namelen;/* size of address */
Struct iovec * msg_iov;/* scatter/gather array */
Size_t msg_iovlen;/* # elements in msg_iov */
Void * msg_control;/* ancillary data, see below */
Size_t msg_controllen;/* ancillary databuffer len */
Int msg_flags;/* flags on received message */
};
Receive data:
# Include <sys/types. h>
# Include <sys/socket. h>
Ssize_t recv (int sockfd, void * buf, size_t len, int flags );
Ssize_t recvfrom (int sockfd, void * buf, size_t len, int flags,
Struct sockaddr * src_addr, socklen_t * addrlen );
Ssize_t recvmsg (int sockfd, struct msghdr * msg, int flags );
Socket options
# Include <sys/types. h>/* See NOTES */
# Include <sys/socket. h>
Int getsockopt (int sockfd, int level, int optname,
Void * optval, socklen_t * optlen );
Int setsockopt (int sockfd, int level, int optname,
Const void * optval, socklen_t optlen );
You can use the preceding functions to set and obtain socket options.