Int send (socket S, const char far * Buf, int Len, int flags );
Both the client and server applications use the send function to send data to the other end of the TCP connection. The client program generally uses the send function to send requests to the server, while the server uses the send function to send responses to the client program.
The first parameter of this function specifies the sender socket descriptor;
The second parameter specifies a buffer for storing the data to be sent by the application;
The third parameter specifies the number of bytes of data to be sent;
The fourth parameter is usually set to 0.
Only the execution process of the send function for Synchronous socket is described here. When this function is called,
(1) Send first compares the length of the data to be sent Len and the length of the sending buffer of socket s. If Len is greater than the length of the sending buffer of S, this function returns socket_error;
(2) If Len is smaller than or equal to the length of the sending buffer of S, send first checks whether the protocol is sending data in the sending buffer of S. If yes, wait until the Protocol finishes sending the data, if the Protocol has not started sending data in the sending buffer of S or there is no data in the sending buffer of S, send will compare the remaining space in the sending buffer of S and Len
(3) If Len is larger than the remaining space, send will wait until the Protocol finishes sending data in the sending buffer of S.
(4) If Len is smaller than the remaining space, send only copies the data in the Buf to the rest of the space (note that it is not send that transmits the data in the sending buffer of S to the other end of the connection, but the protocol is passed, send only copies the data in the Buf to the remaining space in the sending buffer zone of S ).
If the send function successfully copies the data, the actual number of bytes of copy is returned. If an error occurs during sending data copy, the send function returns socket_error; if the network is disconnected when sending data while waiting for the Protocol to send data, the send function also returns socket_error.
Note that the send function successfully copies the data in the Buf to the remaining space of the s sending buffer, and then returns the data. However, the data is not necessarily uploaded to the other end of the connection immediately. If a network error occurs during subsequent transmission, the next socket function will return socket_error. (Each socket function except send must wait until the data in the sending buffer of the socket is transmitted by the protocol before it can continue. If a network error occurs while waiting, then the socket function will return socket_error)
Note: In Unix systems, if the network is disconnected when sending data while waiting for the send protocol, the process that calls send receives a sigpipe signal. The process processes the signal by default and terminates the process.
Tests show that the send function of asynchronous socket can return the corresponding number of bytes when the network is just disconnected, and the select Check is also writable. However, after a few seconds, an error occurs when sending the message again.-1 is returned. Select cannot detect writable data.
2. Recv Function
Int Recv (socket S, char far * Buf, int Len, int flags );
Both the client and server applications use the Recv function to receive data from the other end of the TCP connection. The first parameter of this function specifies the receiver socket descriptor;
The second parameter specifies a buffer that is used to store the data received by the Recv function;
The third parameter specifies the length of the Buf;
The fourth parameter is usually set to 0.
Only the execution process of the Recv function for Synchronous socket is described here. When the application calls the Recv function,
(1) Recv waits for data in the sending buffer of s to be transmitted by the Protocol. If a network error occurs when the Protocol sends data in the sending buffer of S, the Recv function returns socket_error,
(2) If there is no data in the sending buffer of s or the data is successfully sent by the protocol, Recv first checks the receiving buffer of socket S, if there is no data in the s receiving buffer or the Protocol is receiving data, the Recv waits until the Protocol receives the data. When the Protocol receives the data, the Recv function copies the data in the s receiving buffer to the Buf (note that the data received by the protocol may be larger than the length of the Buf, in this case, you need to call the Recv function several times to copy the data in the s receiving buffer. The Recv function only copies data. The protocol is used to receive data ),
The Recv function returns the number of bytes of the actual copy. If a Recv error occurs during copy, socket_error is returned. If the Recv function is interrupted while waiting for the Protocol to receive data, 0 is returned.
Note: In Unix systems, if the network is disconnected when the Recv function is waiting for the Protocol to receive data, the process that calls the Recv will receive a sigpipe signal, the process processes this signal by default.
Blocking means you cannot finish it,
If you are not in a group competition, you should do it first. I want to see if there is anything else. Let me know when it's over.
Let's take the most commonly used send and Recv functions for example...
For example, if you call the send function to send a certain byte, the task of sending data within the system is to transmit data (copy) to the output buffer of the TCP/IP protocol stack, successful execution does not mean that the data has been successfully sent out. If the TCP/IP protocol stack does not have enough buffer to store the data you copied... at this time, the difference between blocking and non-blocking is shown: the socket send function in blocking mode will not return until the system buffer has enough space to copy the data you want to send, for a non-blocking socket, send immediately returns wsaewoulddblock, telling the Caller: "The sending operation is blocked !!! You want to solve it ..."
For the Recv function, the internal working mechanism of the function is actually waiting for the receiving buffer of the TCP/IP protocol stack to notify it: Hi, your data is coming. for a socket in blocking mode, if the receiving buffer of the TCP/IP protocol stack does not notify a result to the receiver, it will never return: system resources are consumed .... for a non-blocking socket, this function will immediately return and tell you: wsaewoulddblock --- "no data now. Let's look back"
When reading data, you must consider that if the size returned by Recv () is equal to the request size, it is likely that there is still data in the buffer zone that has not been read, which means that the event has not been processed, therefore, you need to read it again:
While (RS)
{
Buflen = Recv (activeevents [I]. Data. FD, Buf, sizeof (BUF), 0 );
If (buflen <0)
{
// Because of the non-blocking mode, when errno is eagain, it indicates that no data is readable in the current buffer.
// Here it is treated as the event that has been handled.
If (errno = eagain)
Break;
Else
Return;
}
Else if (buflen = 0)
{
// This indicates that the socket at the peer end is closed normally.
}
If (buflen = sizeof (BUF)
Rs = 1; // read again
Else
Rs = 0;
}
In addition, if the sending end traffic is greater than the receiving end traffic (that is, epoll's program reads faster than the forwarded socket), even if the send () function returns, however, the data in the actual buffer zone is not actually sent to the receiver, so that the read and write operations will continue. When the buffer zone is full, the eagain error will occur (refer to man
And ignore the data sent in this request. therefore, the socket_send () function needs to be encapsulated to handle this situation. This function will try to write the data and then return it. "-1" indicates an error. Within socket_send (), when the write buffer is full (send () returns-1 and errno is eagain), the system will wait and try again. this method is not perfect. Theoretically, it may be blocked within socket_send () for a long time, but there is no better way.
Ssize_t socket_send (INT sockfd, const char * buffer, size_t buflen)
{
Ssize_t TMP;
Size_t Total = buflen;
Const char * P = buffer;
While (1)
{
TMP = Send (sockfd, P, total, 0 );
If (TMP <0)
{
// When sending receives the signal, you can continue writing, but here-1 is returned.
If (errno = eintr)
Return-1;
// If this error is returned when the socket is not blocked, it indicates that the write Buffer Queue is full,
// Retry after delay.
If (errno = eagain)
{
Usleep (1000 );
Continue;
}
Return-1;
}
If (size_t) TMP = total)
Return buflen;
Total-= TMP;
P + = TMP;
}
Return TMP;
}
Share:
Previous: routine for compiling daemon on Linux
Next article: Socket status change diagram
Int send (socket S, const char far * Buf, int Len, int flags );
Both the client and server applications use the send function to send data to the other end of the TCP connection. The client program generally uses the send function to send requests to the server, while the server uses the send function to send responses to the client program.
The first parameter of this function specifies the sender socket descriptor;
The second parameter specifies a buffer for storing the data to be sent by the application;
The third parameter specifies the number of bytes of data to be sent;
The fourth parameter is usually set to 0.
Only the execution process of the send function for Synchronous socket is described here. When this function is called,
(1) Send first compares the length of the data to be sent Len and the length of the sending buffer of socket s. If Len is greater than the length of the sending buffer of S, this function returns socket_error;
(2) If Len is smaller than or equal to the length of the sending buffer of S, send first checks whether the protocol is sending data in the sending buffer of S. If yes, wait until the Protocol finishes sending the data, if the Protocol has not started sending data in the sending buffer of S or there is no data in the sending buffer of S, send will compare the remaining space in the sending buffer of S and Len
(3) If Len is larger than the remaining space, send will wait until the Protocol finishes sending data in the sending buffer of S.
(4) If Len is smaller than the remaining space, send only copies the data in the Buf to the rest of the space (note that it is not send that transmits the data in the sending buffer of S to the other end of the connection, but the protocol is passed, send only copies the data in the Buf to the remaining space in the sending buffer zone of S ).
If the send function successfully copies the data, the actual number of bytes of copy is returned. If an error occurs during sending data copy, the send function returns socket_error; if the network is disconnected when sending data while waiting for the Protocol to send data, the send function also returns socket_error.
Note that the send function successfully copies the data in the Buf to the remaining space of the s sending buffer, and then returns the data. However, the data is not necessarily uploaded to the other end of the connection immediately. If a network error occurs during subsequent transmission, the next socket function will return socket_error. (Each socket function except send must wait until the data in the sending buffer of the socket is transmitted by the protocol before it can continue. If a network error occurs while waiting, then the socket function will return socket_error)
Note: In Unix systems, if the network is disconnected when sending data while waiting for the send protocol, the process that calls send receives a sigpipe signal. The process processes the signal by default and terminates the process.
Tests show that the send function of asynchronous socket can return the corresponding number of bytes when the network is just disconnected, and the select Check is also writable. However, after a few seconds, an error occurs when sending the message again.-1 is returned. Select cannot detect writable data.
2. Recv Function
Int Recv (socket S, char far * Buf, int Len, int flags );
Both the client and server applications use the Recv function to receive data from the other end of the TCP connection. The first parameter of this function specifies the receiver socket descriptor;
The second parameter specifies a buffer that is used to store the data received by the Recv function;
The third parameter specifies the length of the Buf;
The fourth parameter is usually set to 0.
Only the execution process of the Recv function for Synchronous socket is described here. When the application calls the Recv function,
(1) Recv waits for data in the sending buffer of s to be transmitted by the Protocol. If a network error occurs when the Protocol sends data in the sending buffer of S, the Recv function returns socket_error,
(2) If there is no data in the sending buffer of s or the data is successfully sent by the protocol, Recv first checks the receiving buffer of socket S, if there is no data in the s receiving buffer or the Protocol is receiving data, the Recv waits until the Protocol receives the data. When the Protocol receives the data, the Recv function copies the data in the s receiving buffer to the Buf (note that the data received by the protocol may be larger than the length of the Buf, in this case, you need to call the Recv function several times to copy the data in the s receiving buffer. The Recv function only copies data. The protocol is used to receive data ),
The Recv function returns the number of bytes of the actual copy. If a Recv error occurs during copy, socket_error is returned. If the Recv function is interrupted while waiting for the Protocol to receive data, 0 is returned.
Note: In Unix systems, if the network is disconnected when the Recv function is waiting for the Protocol to receive data, the process that calls the Recv will receive a sigpipe signal, the process processes this signal by default.
Blocking means you cannot finish it,
If you are not in a group competition, you should do it first. I want to see if there is anything else. Let me know when it's over.
Let's take the most commonly used send and Recv functions for example...
For example, if you call the send function to send a certain byte, the task of sending data within the system is to transmit data (copy) to the output buffer of the TCP/IP protocol stack, successful execution does not mean that the data has been successfully sent out. If the TCP/IP protocol stack does not have enough buffer to store the data you copied... at this time, the difference between blocking and non-blocking is shown: the socket send function in blocking mode will not return until the system buffer has enough space to copy the data you want to send, for a non-blocking socket, send immediately returns wsaewoulddblock, telling the Caller: "The sending operation is blocked !!! You want to solve it ..."
For the Recv function, the internal working mechanism of the function is actually waiting for the receiving buffer of the TCP/IP protocol stack to notify it: Hi, your data is coming. for a socket in blocking mode, if the receiving buffer of the TCP/IP protocol stack does not notify a result to the receiver, it will never return: system resources are consumed .... for a non-blocking socket, this function will immediately return and tell you: wsaewoulddblock --- "no data now. Let's look back"
When reading data, you must consider that if the size returned by Recv () is equal to the request size, it is likely that there is still data in the buffer zone that has not been read, which means that the event has not been processed, therefore, you need to read it again:
While (RS)
{
Buflen = Recv (activeevents [I]. Data. FD, Buf, sizeof (BUF), 0 );
If (buflen <0)
{
// Because of the non-blocking mode, when errno is eagain, it indicates that no data is readable in the current buffer.
// Here it is treated as the event that has been handled.
If (errno = eagain)
Break;
Else
Return;
}
Else if (buflen = 0)
{
// This indicates that the socket at the peer end is closed normally.
}
If (buflen = sizeof (BUF)
Rs = 1; // read again
Else
Rs = 0;
}
In addition, if the sending end traffic is greater than the receiving end traffic (that is, epoll's program reads faster than the forwarded socket), even if the send () function returns, however, the data in the actual buffer zone is not actually sent to the receiver, so that the read and write operations will continue. When the buffer zone is full, the eagain error will occur (refer to man
And ignore the data sent in this request. therefore, the socket_send () function needs to be encapsulated to handle this situation. This function will try to write the data and then return it. "-1" indicates an error. Within socket_send (), when the write buffer is full (send () returns-1 and errno is eagain), the system will wait and try again. this method is not perfect. Theoretically, it may be blocked within socket_send () for a long time, but there is no better way.
Ssize_t socket_send (INT sockfd, const char * buffer, size_t buflen)
{
Ssize_t TMP;
Size_t Total = buflen;
Const char * P = buffer;
While (1)
{
TMP = Send (sockfd, P, total, 0 );
If (TMP <0)
{
// When sending receives the signal, you can continue writing, but here-1 is returned.
If (errno = eintr)
Return-1;
// If this error is returned when the socket is not blocked, it indicates that the write Buffer Queue is full,
// Retry after delay.
If (errno = eagain)
{
Usleep (1000 );
Continue;
}
Return-1;
}
If (size_t) TMP = total)
Return buflen;
Total-= TMP;
P + = TMP;
}
Return TMP;
}