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, send first compares the length of the data to be sent Len and socket sSending Buffer
Length
,
If Len is greater than the sending buffer length of S, this function returns socket_error; if Len is less than or equal to the sending buffer length of S, send first checks whether the protocol is positive
If the data in the sending buffer of the sending S is waiting for the Protocol to finish sending the data, if the protocol has not started to send the data in the sending buffer of S or there is no data in the sending buffer of S, so
Send compares the remaining space in the sending buffer of S with Len. If Len is larger than the remaining space, send waits until the Protocol sends the data in the sending buffer of S. If Len is smaller than the remaining space
Space size send only copies the data in the Buf to the remaining space (Note that not sending data in the sending buffer of S to the other end of the connection, but passing data through the Protocol,
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.
.
For example
If a network error occurs during subsequent transmission, the next socket function will return socket_error. (Each socket function except send is executing
At the beginning of the line, it is always necessary to wait until the data in the socket sending buffer is transmitted by the Protocol. If a network error occurs while waiting, the socket function returns
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.
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, the Recv waits for the sending buffer of S.
The data in is transmitted by the Protocol. If a network error occurs when the Protocol sends data in the s sending buffer, the Recv function returns socket_error. If no data in the s sending Buffer
After the data is successfully sent by the protocol, Recv first checks the receiving buffer of socket S. If there is no data in the receiving buffer or the Protocol is receiving data, the Recv waits
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 longer than the Buf length. In this case, you must call the Recv function several times to copy the data in the s receiving buffer.The Recv function only copies data, and the protocol is used to actually receive data.
), The Recv function returns the actual number of bytes of 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.
/*************************************** ****************************************/
Int send (
Socket s,
Const char far * Buf,
Int Len,
Int flags
);
How much data can the send function send at most each time? Is it the maximum value of Int?
[Sms88 ]:
Not the maximum value of int
[Sms88 ]:
Theoretically, it depends on the size of a window minus the size of the protocol header.
[Xxyyboy ]:
No, send has a length that is not specified, but a length that is specified.
Int send (
Socket S, // connection
Const char far * Buf, // buffer content
Int Len, // buffer Len
Int flags // unknown
);
The Int function only indicates the return value of the failed message sending, not the length of the returned value.
If you have a buffer, you can send the message.
The data streams from Recv may be intermittent. You need to put them together and decode them.
[Dodoboy ]:
That is to say, if the data in the buffer is too large, I only need to call the send function once, but does the lower layer have a successful transmission or will it be ignored?
[Mudunke775 ]:
The data streams from Recv may be intermittent. You need to put them together and decode them.
//////////////////////////////////////// //////////////////////////
Decoding and merging packages are implemented at the lower layer. Do not decode them by yourself?
[Unsigned ]:
Send
It can be divided into blocking and non-blocking. In blocking mode, if it is normal, it will not return until the data you need to send is sent. If it is not blocking, based on the available buffer size of your socket in the underlying layer
The data in the buffer zone is copied in the past. If the buffer zone is full, the system returns immediately. The returned value only indicates how much data is copied to the buffer zone, however, this does not mean that a few messages are sent.
At the same time, you need to call send again to copy the data to the underlying buffer.
[Iambic ]:
Similar to write.
[Arthur _]:
You can use * setsockopt * to enlarge the buffer.
As a socket, it has two buffers: receive data buffer and send data buffer (this buffer is different from your own defined buffer). When data arrives, the first step is to receive data buffering. However
Then the user reads the data from the buffer, which is the socket acceptance process. The buffer size can be set by setsocketopt (), and the operating system has a default value for it.
Small. If the recipient sends a large amount of data within a short period of time to reach this package, it may not be able to receive it. Therefore, the receiving buffer is in full State and cannot be received when there is data, therefore
An error may be returned when sending. This is not the case when the data volume sent by the recipient is very small. When the data volume is large, the situation is obvious and it is easy to cause a failure to receive the data.
Likewise, the sender's sending buffer has a corresponding problem.
There are several solutions to this problem:
1: Use the setsocketopt () function to set the buffer size of the receiver to a sufficient size;
2: when sending data, the sender determines whether the sending is successful. If the sending fails, the sender resends the data;
3: the receiver is required to respond to the sender after receiving the data. The sender sends the next data only after receiving the response.
Copyright Notice
: During reprinting, please use hyperlinks to indicate the original source and author information of the article and this statement
Http://huu427.blogbus.com/logs/63084689.html
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 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, send compares the data to be sent first.
The length of Len and socket S. If Len is greater than the length of S's sending buffer, this function returns socket_error. If Len is less than or equal to the length of S's sending buffer, then, send checks whether the protocol is sending data in the sending buffer of S.
If so, wait for the Protocol to put data
If the Protocol has not started sending data in the s sending buffer
Or there is no data in the sending buffer of S.
Then, send compares the remaining space in the sending buffer of S and Len. If Len is larger than the remaining space, send will wait until the Protocol sends data in the buffer of S.
After sending, if Len is smaller than the size of the remaining space, send only the data in the Buf
Copy the data to the remaining space (note that the data in the sending buffer of S is not sent by send.
To the other end of the connection, but to the Protocol. Send only refers to the data in the Buf.
Copy to the remaining space in the sending buffer of S ). If the send function copies data
If the copy operation succeeds, the actual number of bytes are returned.
If an error occurs, send will return socket_error; If send is waiting for the Protocol to send data
If the network is disconnected, the send function also returns socket_error.
Note that the send function transfers the data in the Buf
After the data is successfully copied to the remaining space of S's sending buffer, it returns the data.
It 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 always waits for data in the sending buffer of the socket at the beginning of the row execution.
The socket function returns socket_error if a network error occurs while waiting)
Note: In Unix systems, if send is waiting for the Protocol to send data
When the network is disconnected, the process that calls send will receive a sigpipe signal, and the process's default processing of this signal is Process Termination.
Both the client and server applications use the Recv function to receive data from the other end of the TCP connection.
.
The second parameter specifies a buffer, which is used to store the data received by the Recv function.
;
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, the Recv waits for data in the s sending buffer.
If the data transmitted by the Protocol is complete
If a network error occurs, the Recv function returns socket_error. If data or data is not in the sending buffer of S
After the protocol is successfully sent, Recv first checks the receiving buffer of socket S. If there is no data in the receiving buffer
Or the protocol is receiving data.
, Then the Recv will wait until the data is transferred to the Protocol.
Received. When the Protocol changes the data
After receiving the data, the Recv function caches the data in the s receiving buffer.
Copy to Buf (note the data received by the Protocol
It may be longer than the length of the Buf, so in this case, you need to call the Recv function several times to buffer the data received by S.
Copy. The Recv function only copies data.
, Truly 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 waiting for the Protocol to receive data
When the network is interrupted, it returns 0.
Note: In Unix systems, if the Recv function is waiting for the Protocol to receive data
When the network is disconnected, the process that calls Recv will receive a sigpipe signal. The default process for this signal is Process Termination.
The CP protocol is reliable and does not mean that the application sends data over TCP.
It must be reliable. No matter whether it is blocked or not, the size of the send does not represent the amount of data Recv to the peer.
.
In blocking mode, the send function processes the data sent by application requests.
Copy it to the sending cache and send it again after confirmation. however, the existence of the sending cache shows that if the size of the sending cache is greater than that of the request, the send function returns immediately and sends data to the network.
Otherwise, send sends the part of data that cannot be contained in the cache to the network.
And wait for the Peer to confirm before returning (the receiver only needs
When receiving the received cache, the system will confirm that it does not have to wait for the application to call the Recv );
In non-blocking mode, the send function only processes data
Copy to the cache area of the protocol stack. If the available space in the cache area is insufficient, the successful copy size will be returned as much as possible. For example, if the available space in the cache area is 0, -1 is returned, and errno is set to eagain.
In Linux, use sysctl-A | grep net. ipv4.tcp _ WMEM to view the default sending cache size:
Net. ipv4.tcp _ WMEM = 4096 16384 81920
There are three values. The first value is the minimum number of bytes allocated to the socket sending cache, and the second value is the default value (this value will be overwritten by net. Core. wmem_default ).
This value can be increased when the system load is not heavy. The third value is the maximum number of bytes in the sending cache space (this value will be overwritten by net. Core. wmem_max ).
According to the actual test, if the net. net. the value of ipv4.tcp _ WMEM is run according to the changed value. Otherwise, the protocol stack is usually based on net. core. wmem_default and net. core. the value of wmem_max to allocate memory.
Socklen_t sendbuflen = 0; socklen_t Len = sizeof (sendbuflen );
Getsockopt (clientsocket, sol_socket, so_sndbuf, (void *) & sendbuflen,
& Len); printf ("default, sendbuf: % d/N", sendbuflen); sendbuflen =
10240; setsockopt (clientsocket, sol_socket, so_sndbuf,
(Void *) & sendbuflen, Len); getsockopt (clientsocket, sol_socket,
So_sndbuf, (void *) & sendbuflen, & Len );
Printf ("now, sendbuf: % d/N", sendbuflen );
It should be noted that, although the sending cache is set to 10 K, the protocol stack actually doubles it to 20 K.
In practical applications, if the sending end is not blocked, the sending application may seem to have sent 10 KB of data due to network congestion or slow processing at the receiving end.
But only 2 k is sent to the peer cache, and 8 K is in the local cache (not sent or not confirmed by the receiving end). At this time, the data received by the application is received.
2 K. If the receiving application calls the Recv function to obtain 1 k of data
At this moment, one of the following situations occurs:
A. The sending application considers that 10 K of data has been sent.
, Closed socket:
As the active listener of TCP, the sending host will be in the semi-closed status of fin_wait1 (waiting for the ACK of the other party) and send 8 K data in the cache.
If not cleared, it will still be sent to the peer end. If the receiving application is still in Recv, it will receive the remaining 8 k Data
(The acceptor receives the remaining 8 K data before the fin_wait1 status of the sender times out.
.), And then get a message that the Peer socket is closed (Recv returns 0). In this case, close it.
B. The sending application calls send again to send 8 k Data
:
If the sending cache space is 20 K, the available sending cache space is 20-8 = 12 K, which is greater than the 8 K sent by the request. Therefore, the send function transfers the data
After the copy is made, 8192 is returned immediately;
If the size of the sent cache is 12 K, the available size of the sent cache is 12-8 = 4 K, and send () returns 4096, the value returned by the application is smaller than the size of the request sent
You can think that the cache zone is full, and it must be blocked (or wait for the next socket writable signal through select). If the application ignores the problem and calls send again immediately, you will get
-1 value, which is displayed as errno = eagain in Linux.
C. The receiving application processes 1 k of data.
The socket:
The receiving host acts as the active shutdown, and the connection will be in the semi-closed state of fin_wait1 (waiting for the other's ACK). Then, the sending application will receive a socket readable signal (usually
Select calls return socket readable), but when reading it, it will find that the Recv function returns 0. In this case, you should call the close function to close the socket (send to the recipient's ACK );
If the sending application does not process this readable signal, but sends it, there are two cases to consider. If it is called after the sender receives the RST flag
Send, send will return
-1. When errno is set to econnreset, the peer network is disconnected. However, it is also said that the process will receive the sigpipe signal. The default response of this signal is to exit the process, as shown in figure
If this signal is ignored, send returns-1, errno is epipe (unconfirmed), and send works as usual before the sender receives the RST flag.
;
The above is a non-blocking send case. If send is a blocking call and is in a blocking situation (for example, sending a large Buf at a time, beyond the sending cache), the peer socket is closed, send returns the number of successfully sent bytes. If you call send again, it will be the same as above.
D. switch or router network disconnection:
The receiving application processes the received 1 K data.
The remaining 1 K data will be read from the cache
And then it is shown as no data
Readable. In this case, the application needs to process the timeout. Generally, you can set the maximum waiting time for a select statement. If no data exceeded
Read, the socket is considered unavailable.
The sending application will keep sending the remaining data.
Sent to the network, but never confirmed, so the available space in the cache area continues to be 0, which also needs to be processed by the application.
If the application cannot handle the timeout, you can also use the TCP protocol itself. For details, refer to the following in sysctl:
Net. ipv4.tcp _ keepalive_intvl
Net. ipv4.tcp _ keepalive_probes
Net. ipv4.tcp _ keepalive_time
If no buffer space is available within the transport system to hold
The data to be transmitted, send will block unless the socket has been
Placed in nonblocking mode.
If no buffer is provided to store the data to be sent
, Send will block until the socket is set to non-blocking mode,
On nonblocking stream-oriented sockets, the number of bytes written
Can be between 1 and the requested length, depending on Buffer
Availability on both client and server machines.
In the non-blocking stream mode socket, the written bytes can be 1 to the required length, depending on the buffer of the client and server.
The select or wsaeventselect function can be used to determine when it is possible to send more data.
The select or wsaeventselect function can be used to determine when data can be sent.
In blocking mode, sending does not mean that until you send data
It means the data you want to send.
After the sending buffer is put, the system returns directly. Instead of blocking, if the sending buffer does not exist, it will return directly, and blocking will wait for the sending buffer to have space.
Let's take a look at the sending performance in blocking mode. (note the buffer size. Here is 16 K)
1. Send a data smaller than 16 KB
, Send will return immediately
That is to say, send sends the data to be sent.
The sent data will be returned immediately after the sending buffer is put.
The number of bytes is smaller than the buffer size.
2. Send a data larger than 16 KB
, Send does not return immediately, blocking a bit
Send must put all data
It is returned only when it is placed in the buffer. Suppose we send 32 K data.
, When sending the returned data, there are 16 k Data
The other end has been reached, and the remaining 16 K is not sent in the buffer.
In blocking mode
If the message is sent successfully, the returned nbytes must be Len.
Nbytes = Send (m_socket, Buf, Len, 0 );
That is, in the above Code, the sending loop is not necessary.
Let's look at the non-blocking mode.
1. Send a data smaller than 16 KB
, Send immediately returns, and the returned byte length is equal to the length of the sent byte, the condition and blocking mode are the same
The first send, 16384 bytes (16 k) are returned, that is, the buffer is filled.
The second send, sleep for 1000 milliseconds before this time, during which 5000 bytes may have been sent from the buffer and reached the other end, so the buffer is 5000 bytes empty, this time, 5000 is returned, indicating that 5000 bytes are added to the buffer zone.
The third send, which is the same as the second, and contains 6000 bytes.
In the last send, the number of remaining bytes is put. At this time, data is buffered.
.