Asynchronous socket programming-send and receive data
Original Author: Drew Sikora
I wanted to separate sending and receiving as two parts, but at last I decided to explain fd_read slightly, leaving more time to illustrate the more complex fd_write. The fd_read event is very easy to understand. when data is sent, Winsock notifies you of the fd_read event. For each fd_read event, you need to call Recv () as follows ():
Int bytes_recv = Recv (wparam, & Data, sizeof (data), 0 );
This is basically the case. Don't forget to modify wparam above. also, not every call to Recv () will receive a complete packet, because the data may not be sent all at once. therefore, before starting to process the received data, it is best to judge the number of bytes received (that is, the return value of Recv () to see if a complete data packet is received.
Fd_write is relatively troublesome. first, an fd_write event is generated when you establish a connection. however, if you think it is okay to call send () when you receive fd_write, it will be wrong. the fd_write event is triggered only when the sending buffer has more space and can accommodate the data to be sent.
The above-mentioned sending buffer refers to the buffer provided by the system underlying layer. send () First writes data to the sending buffer, and then sends it to the receiving end through the network. you may think that as long as you don't fill up the sending buffer and leave enough space in the sending buffer to accommodate the data to be sent, you will continuously receive fd_write events. hey, it's wrong. the above is just to say that the fd_write event will be triggered when there is more space in the sending buffer, but not when there is enough space to trigger, that is, you must first fill the sending buffer.
The general method is to continuously send data in an infinite loop until the sending buffer is filled up. when the sending buffer is filled up, send () will return socket_error, wsagetlasterror () will return wsawouldblock. if the current socket is in the blocking (synchronous) mode, the program will wait until the sending buffer is empty and then send data. If the socket is non-blocking (asynchronous, then you will get the wsawouldblock error. so as long as we call send () cyclically until the sending buffer is filled up, and then when the buffer is empty, the system will issue the fd_write event. have you ever wondered how difficult it is to point this out? You're lucky. the following is an example of how to handle the fd_write event.
Case fd_write: // you can send data.
{
// Enter the Infinite Loop
While (true)
{
// Read data from the file and save it to packet. Data.
In. Read (char *) & packet. Data, max_packet_size );
// Send data
If (send (wparam, (char *) (& Packet), sizeof (packet), 0) = socket_error)
{
If (wsagetlasterror () = wsaewouldblock)
{
// When the sending buffer is full, exit the loop.
Break;
}
Else // other errors
{
// Display Error information and exit.
Cleanup ();
Return (0 );
}
}
}
} Break;
As you can see, implementation is actually not difficult at all. you just confused some concepts. this method can be used to exit the loop when the sending buffer is full. then, when the buffer zone is empty, the system will trigger another fd_write event, so you can continue to send data.
Before you start using the new knowledge, I would like to explain the time to use the fd_write event. if you do not send a large volume of data at a time, don't think about using the fd_write event. The reason is simple-if you expect to send data when receiving the fd_write event, however, you cannot send enough data to fill the sending buffer, so you can only receive the fd_write triggered when the connection is just established-the system will not trigger more fd_write. so when you only send as little data as possible, forget the fd_write mechanism and directly call send () whenever you want to send data ().
Conclusion
This is the longest article I have ever written. I tried to write it as short as possible to attract your attention, but there is too much content to include. when you just used an asynchronous socket, if you do not understand it correctly, you will actually spoof yourself. I hope my articles will teach you how to use them.
___________________________________
This is part of an article I found on Google. although some of the original author's views do not seem correct, the article is easy to understand. in fact, if you want to receive the fd_write event and you cannot fill the sending buffer first, you can call wsaasyncselect (..., fd_write ). if the current sending buffer is empty, the system will immediately send you an fd_write event.
Fd_write message. The casyncsocket class of MFC maps it to the onsend () function. fd_read message, which is mapped to the onreceive () function.