Author: DREW SIKORA
I have wanted to separate the send and receive as two parts, but in the end, I decided to explain the fd_read, leaving more time to explain more complex FD_WRITE, FD_READ events very easy to master. When there is data to send, Winsock will Inform you with fd_read events, for each FD_READ event, you need to call RECV ():
INT BYTES_RECV = Recv (WParam, & Data, SizeOf (DATA), 0);
Basically, don't forget to modify the above WParam. Also, not necessarily each call RECV () will receive a complete packet, because the data may not be sent all once. So start processing and receipt Before the data, it is best to determine the number of bytes received (ie, the return value of the RECV ()) to see if it is received.
FD_WRITE is relatively troubles. First, when you have established a connection, a fd_write event will be generated. But if you think that sending Send () when you receive FD_WRITE, you will be big, then it is wrong. FD_WRITE event is only sent There are more space in the buffer to accommodate data that you need to send.
The so-called transmission buffer is referring to the buffer provided by the system underlayer. Send () first writes the data into the transmission buffer and then sends it to the receiving end through the network. You may want to fill in the send buffer Full, let the send buffer maintain enough space to accommodate the data you need to send, then you will continue to receive the fd_write event. Hey, wrong. Only the FD_WRITE event is in the send buffer has more vacancy It will trigger, but not when there is enough vacancy, it means that you have to fill the send buffer first.
The usual method is to send data in an infinite loop until the send buffer is filled. When the buffer is filled, send () will return SOCKET_ERROR, WsageTlasTerror () will return WSAWOULDBLOCK. If the current socket In blocking (synchronous) mode, the program will wait until the buffer is sent and then sending data; if socket is non-blocking (asynchronous), then you will get a WSAWOULDBLOCK error. So as long as we first loop call send () until send The buffer is filled, and then when the buffer is empty, the system will issue an FD_WRITE event. Have you ever thought that I can point out how it is coming out, you can be lucky. Below is an FD_WRITE event example of.
CASE fd_write: // You can send data {// Enter infinite loop while (true) {// read data from the file, save it into 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) {// The send buffer is already full, exit Cycle. Break;} else // Other Error {// Display error information and exit. Cleanup (); return (0);}}}}}}}}} Break;
See it, realize it is not difficult. You just fill some concepts. Use such a sending method, you can exit the loop when sending the buffer is full. Then, when the buffer is empty The system will trigger another FD_WRITE event, so you can continue to send data.
Before you start using new knowledge, I also want to explain the timing of the FD_WRITE event. If you don't send a large amount of data in one time, don't think about using the fd_write event, the reason is simple - if you send It is expected to send data when receiving the fd_write event, but can not send enough data to fill the buffer, then you can only receive the fd_write-system that is triggered when the connection is just built - the FD_WRITE does not trigger more fd_write . So when you just send as few data as possible, I forget the FD_WRITE mechanism. When you want to send data, call Send (). Conclusion This is the longest article I have written. I I have also tried to write it to some shortest possible to attract your attention, but there are too many contents to include. When you just use asynchronous socket, if you don't understand it correctly, you will really put yourself. I I hope my article teaches you how to use them. __________________________________
This is part of the article I have learned on Google. Although the parties' partners seem to be not correct, the article is readily understood. In fact, if you want to receive the fd_write event and you can't fill Full send buffer, you can call WSaasyncSelect (..., fd_write). If the currently buffer has space, the system will send you FD_WRITE events immediately.
FD_WRITE message, MFC's CasyncSocket class maps it to an onsend () function. FD_READ message, is mapped to the onRecEive () function.