What is socket
A socket interface is an API of a TCP/IP network. A socket interface defines many functions or routines. programmers can use it to develop applications on a TCP/IP network. To learn TCP/IP network programming on the internet, you must understand the socket interface.
The socket interface designer first places the interface in the UNIX operating system. If you understand the input and output of Unix systems, you can easily understand socket. Network
Socket data transmission is a special type of I/O, and socket is also a file descriptor. Socket also has a function called socket () similar to opening a document. This function returns an integer socket descriptor, and subsequent connection establishment and data transmission operations are implemented through this socket. There are two common socket types: stream socket
(Sock_stream) and datagram socket (sock_dgram ). Streaming is a connection-oriented socket for connection-oriented TCP Service applications; datagram socket is a connectionless socket that corresponds to connectionless UDP Service applications.
Socket Creation
To establish a socket, the program can call the socket function, which returns a handle similar to the document descriptor. The socket function is prototype:
Int socket (INT domain, int type, int
Protocol );
Domain indicates the protocol family used, usually pf_inet, indicating the Internet protocol family (TCP/IP protocol family). The type parameter specifies the socket type:
Sock_stream
Or sock_dgram, the socket interface also defines the original socket (sock_raw), allowing the program to use the low-level protocol; Protocol is usually assigned a value of "0 ".
The socket () call returns an integer socket descriptor, which can be used in subsequent calls.
The socket descriptor is a pointer to the internal data structure, which points to the descriptor table entry. When the socket function is called, the socket execution body establishes a socket. In fact, "Creating a socket" means allocating storage space for a socket data structure. The socket execution body is used to manage the descriptor table.
A network connection between two network programs includes five types of information: communication protocol, local Protocol address, local host port, remote host address, and remote protocol port. The socket data structure contains these five types of information.
Socket Configuration
After a socket descriptor is returned through a socket call, you must configure this socket before using the socket for network transmission. The connection-oriented Socket Client saves local and remote information in the socket data structure by calling the connect function. The client and server without socket connection, together with the server for socket connection, call
Bind function to configure local information.
The BIND function associates the socket with a port on the machine, and then you can listen for service requests on the port. The BIND function is prototype:
Int BIND (INT sockfd, struct sockaddr * my_addr, int addrlen );
Sockfd is the socket descriptor returned by the socket function. my_addr is a sockaddr pointer pointing to information including the local IP address and port number. addrlen is often configured as sizeof (struct
Sockaddr ).
The struct sockaddr structure type is used to save socket information:
Struct sockaddr
{
Unsigned short sa_family;/* address family, af_xxx */
Char sa_data [14];/* 14
Byte Protocol address */
};
Sa_family is generally af_inet, which represents the Internet (TCP/IP) address family. sa_data contains the IP address and port number of the socket.
There is also a structure type:
Struct sockaddr_in {
Short int sin_family;/* address family
*/
Unsigned short int sin_port;/* Port Number */
Struct in_addr sin_addr;
/* IP Address */
Unsigned char sin_zero [8];/* fill in 0 to keep the same size as struct sockaddr
*/
};
This structure is more convenient to use. Sin_zero is used to fill the sockaddr_in structure with the struct
The same length of sockaddr can be set to zero using the bzero () or memset () function. Pointing to sockaddr_in
The pointer to sockaddr and the pointer to sockaddr can be converted to each other, which means that if the required parameter type of a function is sockaddr, you can
The addr_in pointer is converted to the sockaddr pointer; or vice versa.
When using the BIND function, you can use the following value assignment to automatically obtain the local IP address and randomly obtain an unused port number:
My_addr.sin_port = 0;/* The system randomly selects an unused Port Number */
My_addr.sin_addr.s_addr =
Inaddr_any;/* enter the local IP Address
*/
By setting my_addr.sin_port to 0, the function automatically selects an unused port for you to use. Similarly, by setting my_addr.sin_addr.s_addr to inaddr_any, the system automatically fills in the local IP address.
Note that when using the BIND function, you need to convert sin_port and sin_addr to the network byte priority, while sin_addr does not need to be converted.
There are two types of computer data storage priorities: high byte priority and low byte priority. Data on the internet is transmitted over the network in the high byte priority. Therefore, for machines that store data in the low byte priority mode, data transmission over the Internet requires conversion, otherwise, data inconsistency may occur.
Below are several bytes sequence conversion functions:
· Htonl (): converts 32-bit values from the host's byte order to the network's byte order
· Htons (): converts 16-bit values from the host's byte order to the network's byte order
· Ntohl (): converts 32-bit values from the network byte order to the host byte order.
· Ntohs (): converts 16-bit values from the network byte order to the host byte order.
The BIND () function returns 0 when the call is successful. If an error occurs, it returns "-1" and sets errno as the corresponding error number. Note that do not set the port number to a value smaller than 1024 when calling the BIND function, because the port numbers from 1 to 1024 are reserved, you can select any unused port number in the range greater than 1024.
Establish a connection
Connection-oriented client programs use the connect function to configure the socket and establish a TCP connection with the remote server. The function prototype is:
Int connect (INT sockfd, struct sockaddr * serv_addr, int addrlen );
Sockfd
Is the socket descriptor returned by the socket function; serv_addr is a pointer containing the IP address and port number of the remote host; addrlen is the length of the remote geological structure.
The connect function returns-1 when an error occurs, and errno is configured as the corresponding error code. For client programming, you do not need to call BIND (), because in this case, you only need to know the IP address of the target machine, and you do not need to care about which port the customer uses to establish a connection with the server, the socket executor automatically selects an unused port for your program and notifies you when the program data is interrupted.
Connect function starts a direct connection with the remote host. The socket must be connected to the remote host only when the connection-oriented client program uses the socket. No connection protocol never establishes direct connection. The connection-oriented server never starts a connection, but passively listens to client requests on the protocol port.
The listen function enables the socket to be in passive listening mode, creates an input data queue for the socket, and stores incoming service requests in this queue until the program processes them.
Int
Listen (INT sockfd, int backlog );
Sockfd is the socket returned by the Socket System Call.
Descriptor; backlog specifies the maximum number of requests allowed in the Request queue. incoming connection requests will wait for accept () in the queue (refer to the following ). Backlog limits the number of requests waiting for service in the queue. The default value is 20 for most systems. If a service request arrives, the input queue is full, and the socket rejects the connection request, the customer will receive an error message.
When an error occurs, the listen function returns-1 and returns the error code errno.
The accept () function allows the server to receive client connection requests. After the input queue is established, the server calls the accept function and then sleeps and waits for the client's connection request.
Int
Accept (INT sockfd, void * ADDR, int
* Addrlen );
Sockfd is the socket descriptor to be monitored. ADDR is usually a pointer to the sockaddr_in variable, this variable is used to store the information of the host requesting the service (a host sends this request from a port); addrten is usually a point value of sizeof (struct
Sockaddr_in. When an error occurs, the accept function returns-1 and sets the corresponding errno value.
First, when the accept function monitors
When the socket receives the connection request, the socket executor establishes a new socket, and the executor associates the new socket with the address of the Request connection process, the initial socket that receives the service request can still be in the previous
The new socket descriptor can be used for data transmission.
Data Transmission
The send () and Recv () functions are used for data transmission on the connected socket.
The send () function is prototype:
Int send (int
Sockfd, const void * MSG, int Len, int
Flags );
Sockfd is the socket descriptor you want to use to transmit data; MSG is a pointer to the data to be sent; Len is the length of the data in bytes; flags is usually set to 0 (for the usage of this parameter, refer to the man Manual ).
The send () function returns the number of actually sent bytes, which may be less than the data you want to send. In the program, the return value of send () should be compared with the number of bytes to be sent. When the return value of send () does not match Len, this situation should be processed.
Char
* MSG = "Hello! ";
Int Len, bytes_sent;
......
Len =
Strlen (MSG );
Bytes_sent = Send (sockfd, MSG, Len, 0 );
......
The Recv () function is prototype:
Int Recv (INT sockfd, void * Buf, int Len, unsigned int
Flags );
Sockfd is the socket descriptor for receiving data; Buf
Is the buffer for storing received data; Len is the buffer length. Flags is also set to 0. Recv () returns the number of actually received bytes. If an error occurs,-1 is returned and the corresponding errno value is set.
Sendto () and recvfrom () are used for data transmission in the connectionless datagram socket mode. Because the local socket does not establish a connection with the remote machine, the destination address should be specified when sending data.
The prototype of the sendto () function is:
Int sendto (INT sockfd, const void * MSG, int Len, unsigned int flags, const struct
Sockaddr * To, int
Tolen );
This function has two more parameters than the send () function. To indicates the IP address and port number of the host, while tolen is often assigned sizeof (struct
Sockaddr ). The sendto function also returns the actual length of data bytes or-1 in case of a sending error.
The original recvfrom () function is:
Int
Recvfrom (INT sockfd, void * Buf, int Len, unsigned int flags, struct sockaddr
* From, int * fromlen );
From is a struct.
Sockaddr type variable, which saves the IP address and port number of the source machine. Fromlen is often set to sizeof (struct
Sockaddr ). When recvfrom () is returned, fromlen contains the number of data bytes actually stored in from. The recvfrom () function returns the number of bytes received or-1 if an error occurs, and the corresponding errno is set.
If you call the connect () function on the datagram socket, you can also use send () and Recv () for data transmission, but the socket is still a datagram socket, the UDP Service at the transport layer is used. However, when sending or receiving data reports, the kernel automatically adds the object and source address information.
End Transmission
After any data operation is completed, you can call the close () function to release the socket and stop any data operation on the socket:
Close (sockfd );
You can also call the shutdown () function to close the socket. This function allows you to stop data transmission in a certain direction, while data transmission in one direction continues. If you can disable write operations on a socket, you can continue to accept data on the socket until you read any data.
Int Shutdown (INT sockfd, int how );
Sockfd is the descriptor of the socket to be closed. Parameters
How allows you to select the following methods for the shutdown operation:
· 0 ------- you are not allowed to continue receiving data.
· 1 ------- data cannot be sent again
· 2 ------- you are not allowed to send or receive data,
· If both allow, close () is called ()
If the shutdown operation succeeds, 0 is returned. If an error occurs,-1 is returned and the corresponding errno is set.
Socket programming instance
The server in the Code instance sends the string "Hello, you are
Connected! ". If you run the software on the server and the client runs the software on the client, the client receives the string.
The software code of the server is as follows:
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define servport 3333/* server listening port number
*/
# Define backlog 10/* Maximum number of simultaneous connection requests */
Main ()
{
Int
Sockfd, client_fd;/* sock_fd: Listener socket; client_fd: Data Transmission socket */
Struct
Sockaddr_in my_addr;/* local address information */
Struct sockaddr_in remote_addr ;/*
Client address information */
If (sockfd = socket (af_inet, sock_stream, 0) =-1 ){
Perror ("socket creation error! "); Exit (1 );
}
My_addr.sin_family = af_inet;
My_addr.sin_port = htons (servport );
My_addr.sin_addr.s_addr =
Inaddr_any;
Bzero (& (my_addr.sin_zero), 8 );
If (BIND (sockfd, (struct
Sockaddr *) & my_addr, sizeof (struct sockaddr) =-1 ){
Perror ("BIND error! ");
Exit (1 );
}
If (Listen (sockfd, backlog) =
-1 ){
Perror ("Listen error! ");
Exit (1 );
}
While (1 ){
Sin_size = sizeof (struct sockaddr_in );
If (client_fd = accept (sockfd,
(Struct sockaddr *) & remote_addr, & sin_size) =-1 ){
Perror ("Accept error ");
Continue;
}
Printf ("received
Connection from % s/n ", inet_ntoa (remote_addr.sin_addr ));
If (! Fork ()){/*
Child Process Code segment */
If (send (client_fd, "Hello, you are connected! /N ", 26, 0) =
-1)
Perror ("send error! ");
Close (client_fd );
Exit (0 );
}
Close (client_fd );
}
}
}
The workflow of the server is as follows: first call the socket function to create a socket, then call the BIND function to bind it to the local address together with a local port number, and then call
Listen listens on the corresponding socket. When accpet receives a connection service request, a new socket is generated. The server displays the IP address of the client and sends the string "Hello, you
Are
Connected! ". Close the socket.
The fork () function in the Code instance generates a sub-process to process the data transmission part. The value returned by the fork () Statement for the sub-process is 0. Therefore, the IF statement containing the fork function is the sub-process code part, and the parent Process Code part after the if statement is executed concurrently.
The client code is as follows:
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define servport 3333
# Define maxdatasize 100/* maximum data transmission volume each time */
Main (int
Argc, char * argv []) {
Int sockfd, recvbytes;
Char
Buf [maxdatasize];
Struct hostent * Host;
Struct sockaddr_in
Serv_addr;
If (argc h_addr );
Bzero (& (serv_addr.sin_zero), 8 );
If (connect (sockfd, (struct sockaddr *) & serv_addr ,/
Sizeof (struct
Sockaddr) =-1 ){
Perror ("Connect error! ");
Exit (1 );
}
If
(Recvbytes = Recv (sockfd, Buf, maxdatasize, 0) =-1)
{
Perror ("Recv error! ");
Exit (1 );
}
Buf [recvbytes] = '/0 ';
Printf ("Received: % s", Buf );
Close (sockfd );
}
The client first obtains the Server IP address through the server domain name, creates a socket, calls the connect function to establish a connection with the server, receives data sent from the server after the connection is successful, and closes the socket.
The gethostbyname () function completes domain name conversion. Because IP addresses are hard to remember and read/write, domain names are often used to represent hosts for convenience, which requires domain name and IP address conversion. Function prototype:
Struct hostent * gethostbyname (const char * Name );
The structure type returned by the function as hosten. Its definition is as follows:
Struct hostent {
Char * h_name;/* Host's official Domain Name
*/
Char ** h_aliases;/* an array of host aliases ending with null */
Int h_addrtype ;/*
The type of the returned address, which is AF-INET in an Internet environment */
Int h_length;/* the length of the address in bytes */
Char
** H_addr_list;/* an array ending with 0, containing any address of the Host */
};
# Define h_addr
H_addr_list [0]/* The first address in H-ADDR-list */
When the gethostname () call is successful, the return point is struct.
Hosten pointer. If the call fails,-1 is returned. When gethostbyname is called, you cannot use the perror () function to output error messages. Instead, use the herror () function to output error messages.
The principle of a connectionless client/server program is the same as that of a connected Client/Server. The difference between the two is that customers in a connectionless Client/Server generally do not need to establish a connection, when sending and receiving data, you must specify the address of the remote machine.
Blocking and non-blocking
The blocking function does not allow the program to call another function until it completes the specified task. For example, when a program executes a function call to read data, the program does not execute the next program statement until the function completes the read operation. When the server runs the accept statement without a customer connection request, the server stops waiting for the connection request on the accept statement. This is called blocking ). The non-blocking operation can be completed immediately. For example, if you want the server to check whether a client is waiting for a connection, you can accept the connection. Otherwise, you can continue to do other things by configuring the socket as a non-blocking method. The non-blocking Socket enables the Accept call to return immediately when no client is waiting.
# Include
# Include
......
Sockfd =
Socket (af_inet, sock_stream, 0 );
Fcntl (sockfd, f_setfl, o_nonblock );
......
By configuring the socket as a non-blocking method, you can implement "polling" Several sockets. When an attempt is made to read data from a non-blocking socket without data waiting for processing, the function will return immediately, the returned value is-1, and the errno value is ewouldblock. However, this "Round Robin" will make the CPU in a busy waiting mode, thus reducing performance and wasting system resources. And call
Select () effectively solves this problem. It allows you to hook up the process itself and enable the system kernel to listen to any activity of a set of file descriptors required by the system kernel, as long as the activity is confirmed on any monitored document descriptor, the Select () call will return information indicating that the document descriptor is prepared, so as to select random changes for the process, it is not a waste of testing input by the process itself.
CPU overhead. The prototype of the select function is:
Int select (INT numfds, fd_set * readfds, fd_set
* Writefds,
Fd_set * required TFDs, struct timeval
* Timeout );
Readfds, writefds, and limit TFDs are the collection of read, write, and exception handling document descriptors monitored by select. If you want to determine whether data can be read from the standard input and a socket descriptor, you only need to add the standard input file descriptor 0 and the corresponding sockdtfd to the readfds set; the numfds value is the file descriptor with the highest number to be checked plus 1. In this example, the numfds value should be sockfd + 1. When the SELECT statement is returned, readfds will be modified, indicates that a file descriptor is being read. You can test it through fd_issset. To configure, reset, and test the corresponding file descriptor in fd_set, a set of macros are provided:
Fd_zero (fd_set * Set) ---- clears a file descriptor set;
Fd_set (int fd, fd_set
* Set) ---- Add a document descriptor to the document descriptor set;
Fd_clr (int fd, fd_set
* Set) ---- clears a file descriptor from the file descriptor set;
Fd_isset (int fd, fd_set
* Set) ---- test whether the file descriptor is set.
The timeout parameter is a pointer to struct.
Timeval pointer, which enables select () to return if no file descriptor is ready after waiting for timeout for a long time. Struct timeval data structure:
Struct timeval {
Int TV _sec;/* seconds */
Int TV _usec ;/*
Microseconds
*/
};
POP3 client instance
The following code example is based on the POP3 client protocol and connects to the mail server and retrieves emails from a specified user account. Commands that interact with the email server are stored in the string array popmessage. The program sends these commands in sequence through a do-while loop.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define pop3servport 110
# Define maxdatasalize 4096
Main (INT argc, char
* Argv []) {
Int sockfd;
Struct hostent * Host;
Struct sockaddr_in
Serv_addr;
Char * popmessage [] = {
"User USERID/R/N ",
"Pass
Password/R/N ",
"STAT/R/N ",
"List/R/N ",
"Retr 1/R/N ",
"DELE
1/R/N ",
"Quit/R/N ",
Null
};
Int ilength;
Int imsg = 0;
Int
Iend = 0;
Char
Buf [maxdatasize];
If (host = gethostbyname ("Your. Server") = NULL)
{
Perror ("gethostbyname error ");
Exit (1 );
}
If (sockfd =
Socket (af_inet, sock_stream, 0) =-1 ){
Perror ("Socket
Error ");
Exit (1 );
}
Serv_addr.sin_family = af_inet;
Serv_addr.sin_port = htons (pop3servport );
Serv_addr.sin_addr
= * (Struct in_addr
*) Host-> h_addr );
Bzero (& (serv_addr.sin_zero), 8 );
If
(Connect (sockfd, (struct sockaddr *) & serv_addr, sizeof (struct
Sockaddr) =-1 ){
Perror ("Connect error ");
Exit (1 );
}
Do
{
Send (sockfd, popmessage [imsg], strlen (popmessage [imsg]), 0 );
Printf ("have
Sent:
% S ", popmessage [imsg]);
Ilength = Recv (sockfd, BUF + iend, sizeof (BUF)-iend, 0 );
Iend + = ilength;
Buf [iend] = '/0 ';
Printf ("received:
% S, % d/N ", Buf, imsg );
Imsg ++;
} While
(Popmessage [imsg]);
Close (sockfd );
}
Socket programming in Unix/Linux
Network socket data transmission is a special type of I/O, and socket is also a file descriptor.
Socket also has a function that calls socket () similar to opening a document. This function returns an integer socket descriptor, and subsequent connection establishment and data transmission operations are performed through this
Socket implementation. There are two common socket types: stream socket
(Sock_stream) and datagram socket (sock_dgram ). Streaming is a connection-oriented socket for connection-oriented TCP Service applications; datagram socket is a connectionless socket that corresponds to connectionless UDP Service applications.
The socket descriptor is a pointer to the internal data structure, which points to the descriptor table entry. When the socket function is called, the socket execution body establishes a socket. In fact, "Creating a socket" means allocating storage space for a socket data structure. The socket execution body is used to manage the descriptor table. A network connection between two network programs includes five types of information: communication protocol, local Protocol address, local host port, remote host address, and remote protocol port. The socket data structure contains these five types of information.
The struct sockaddr structure type is used to save socket information:
Struct sockaddr {
Unsigned short sa_family;/* address family, af_xxx */
Char sa_data [14];/* 14
Byte Protocol address */
};
Sa_family is generally af_inet, which represents the Internet (TCP/IP) address family. sa_data contains the IP address of the socket and
The port number.
There is also a structure type:
Struct sockaddr_in {
Short int sin_family ;/*
Address Family */
Unsigned short int sin_port;/* Port Number */
Struct in_addr
Sin_addr;/* IP Address */
Unsigned char sin_zero [8];/* fill 0 to keep and struct
Sockaddr of the same size */
};
You can use the bzero () or memset () function to set it to zero. Pointing to sockaddr_in
And the pointer pointing to sockaddr
Mutual conversion, which means that if the parameter type required by a function is sockaddr, you can point
The addr_in pointer is converted to the sockaddr pointer; or vice versa.
When using the BIND function, you need to convert sin_port and sin_addr to the network byte priority, while sin_addr does not need to be converted.
There are two types of computer data storage priorities: high byte priority and low byte priority. Data on the Internet is in high byte
Data is transmitted over the network in priority. Therefore, for machines that store data in low byte mode, data is transmitted over the Internet.
Data must be converted. Otherwise, data inconsistency may occur.
Below are several bytes sequence conversion functions:
· Htonl (): converts 32-bit values from the host's byte order to the network's byte order
· Htons (): converts 16-bit values from the host's byte order to the network's byte order
· Ntohl (): converts 32-bit values from the network byte order to the host byte order.
· Ntohs (): converts 16-bit values from the network byte order to the host byte order.
The BIND () function returns 0 when the call is successful. If an error occurs, it returns "-1" and sets errno as the corresponding error number. Note:
Yes. Generally, do not set the port number to a value smaller than 1024 when calling the BIND function. Because the port numbers from 1 to 1024 are reserved, you can select
Any unused port number greater than 1024.
Establish a connection
The connection-oriented client program uses the connect function to configure the socket and establish a TCP connection with the remote server. The prototype of the function is int connect (int
Sockfd, struct sockaddr * serv_addr, int addrlen );
Sockfd is the socket descriptor returned by the socket function, serv_addr is a pointer containing the IP address and port number of the remote host, and addrlen is the length of the remote address structure. The connect function returns-1 when an error occurs, and errno is configured as the corresponding error code. For client programming, you do not need to call BIND (), because in this case, you only need to know the IP address of the target machine, and you do not need to care about which port the customer uses to establish a connection with the server, the socket executor automatically selects an unused port for your program and notifies you when the program data is interrupted. Connect
Function start and remote host direct connection. The socket must be connected to the remote host only when the connection-oriented client program uses the socket. No connection protocol never establishes direct connection. The connection-oriented server never starts a connection, but passively listens to client requests on the protocol port.
The listen function enables the socket to be in passive listening mode and creates an input data queue for the socket to send incoming service requests.
Save in this queue until the program processes them. Int listen (INT sockfd, int backlog); sockfd
Is the socket returned by the Socket System Call.
Descriptor; backlog specifies the maximum number of requests allowed in the Request queue. incoming connection requests will wait for accept () in the queue (refer to the following ). Backlog limits the number of requests waiting for service in the queue. The default value is 20 for most systems. If the input queue is full when a service request arrives
The socket rejects the connection request and the customer receives an error message. When an error occurs, the listen function returns-1 and returns the error code errno.
The accept () function allows the server to receive client connection requests. After the input queue is established, the server calls the accept function and
Sleep and wait for the customer's connection request. Int accept (INT sockfd, void * ADDR, int * addrlen );
Sockfd is the socket descriptor to be monitored. ADDR is usually a pointer to the sockaddr_in variable, this variable is used to store the information of the host requesting the service (a host sends this request from a port); addrlen is usually a point value of sizeof (struct
Sockaddr_in. When an error occurs, the accept function returns-1 and sets the corresponding errno value. When the socket monitored by the accept function receives a connection request, the socket executor establishes a new socket, which associates the new socket with the address of the Request connection process, the initial socket that receives the service request can still be in the previous
The new socket descriptor can be used for data transmission.
Data Transmission
(Connection-oriented TCP)
The send () and Recv () functions are used for data transmission on the connected socket. The send () function is prototype:
Int send (INT sockfd,
Const void * MSG, int Len, int flags );
Sockfd is the socket descriptor you want to use to transmit data; MSG is a pointer to the data to be sent; Len is the length of the data in bytes; flags is usually set to 0. The send () function returns the number of actually sent bytes, which may be less than the data you want to send. In the program, the return value of send () should be compared with the number of bytes to be sent. When the return value of send () does not match Len, this situation should be processed.
Int Recv (INT sockfd, void * Buf, int Len, unsigned int flags );
Sockfd is the socket descriptor for receiving data; Buf
Is the buffer for storing received data; Len is the buffer length. Flags is also set to 0. Recv () returns the number of actually received bytes. If an error occurs,-1 is returned and the corresponding errno value is set.
(No UDP connection)
Sendto () and recvfrom () are used for data transmission in the connectionless datagram socket mode. Because the local socket does not establish a connection with the remote machine, the destination address should be specified when sending data.
Int sendto (INT sockfd, const void * MSG, int Len, unsigned int flags, const struct
Sockaddr * To, int
Tolen); this function has two more parameters than the send () function. To indicates the IP address and port number of the host, while tolen is often assigned sizeof (struct
Sockaddr ). The sendto function also returns the actual length of data bytes or-1 in case of a sending error.
Int recvfrom (int
Sockfd, void * Buf, int Len, unsigned int flags, struct sockaddr * From, int * fromlen );
From is a variable of the struct sockaddr type, which saves the IP address and port number of the source machine. Fromlen is often set to sizeof (struct
Sockaddr ). When recvfrom () is returned, fromlen contains the number of data bytes actually stored in from.
The recvfrom () function returns the number of bytes received or-1 if an error occurs, and the corresponding errno is set.
End Transmission
After any data operation is completed, you can call the close () function to release the socket and stop any
What data operations: Close (sockfd );
You can also call the shutdown () function to close the socket. This function allows you to stop data transmission in a certain direction, while data transmission in one direction continues. If you can disable write operations on a socket, you can continue to accept data on the socket until you read any data. Sockfd
Is the descriptor of the socket to be closed. The how parameter allows you to select the following methods for the shutdown operation: 0 ------- you are not allowed to continue receiving data 1 ------- you are not allowed to continue sending data
2 ------- you are not allowed to send or receive data. If both are allowed, close () is called ()
If the shutdown operation succeeds, 0 is returned. If an error occurs,-1 is returned and the corresponding errno is set.