OnReceive stop being called [modified]
-
Hopefully somebody can help me with this problem. I am fairly new with socket connection. I know you guys will want to see some code but unfortunately this is hard to do as my code is on a classified system. I would prefer not to have to type all the necessary code. However if I have to I will. I have a server-client socket connect and I use CSocket. Once the connection is made, the server sends 168-byte message to the client once per second. In the client OnReceive function I read the data and then write it to a file. In the OnIdle function of the client I also check if the connection with the server is still up by sending a one-byte message to the server. My problem is that it works for a while and then the client OnReceive stops being called by the framework. Using debugging I know for a fact that the server is still sending the 168-byte messages every seconds without any errors. I also know that the client is still sending the one-byte message to the server and the server is still receiving it. Both programs seem to be working just fine except for the fact that the OnReceive is no longer being called and therefore I am no longer writing data to the file. Anybody can help me? Thanks! BTW it never stops at the same place. I can sometimes receive 2K but other times I can receive a lot more. The most I got was 94,168 bytes. -- modified at 13:41 Tuesday 6th February, 2007
jpyp
-
Hopefully somebody can help me with this problem. I am fairly new with socket connection. I know you guys will want to see some code but unfortunately this is hard to do as my code is on a classified system. I would prefer not to have to type all the necessary code. However if I have to I will. I have a server-client socket connect and I use CSocket. Once the connection is made, the server sends 168-byte message to the client once per second. In the client OnReceive function I read the data and then write it to a file. In the OnIdle function of the client I also check if the connection with the server is still up by sending a one-byte message to the server. My problem is that it works for a while and then the client OnReceive stops being called by the framework. Using debugging I know for a fact that the server is still sending the 168-byte messages every seconds without any errors. I also know that the client is still sending the one-byte message to the server and the server is still receiving it. Both programs seem to be working just fine except for the fact that the OnReceive is no longer being called and therefore I am no longer writing data to the file. Anybody can help me? Thanks! BTW it never stops at the same place. I can sometimes receive 2K but other times I can receive a lot more. The most I got was 94,168 bytes. -- modified at 13:41 Tuesday 6th February, 2007
jpyp
Hmmm sockets have been around for 24 years and you're using CSocket - classified socket code? :) Just teasin. Anyway, is the protocol TCP? If you are using OnIdle(), what are you returning from it? Does it perform better if you move the mouse around occasionally? Mark
-
Hopefully somebody can help me with this problem. I am fairly new with socket connection. I know you guys will want to see some code but unfortunately this is hard to do as my code is on a classified system. I would prefer not to have to type all the necessary code. However if I have to I will. I have a server-client socket connect and I use CSocket. Once the connection is made, the server sends 168-byte message to the client once per second. In the client OnReceive function I read the data and then write it to a file. In the OnIdle function of the client I also check if the connection with the server is still up by sending a one-byte message to the server. My problem is that it works for a while and then the client OnReceive stops being called by the framework. Using debugging I know for a fact that the server is still sending the 168-byte messages every seconds without any errors. I also know that the client is still sending the one-byte message to the server and the server is still receiving it. Both programs seem to be working just fine except for the fact that the OnReceive is no longer being called and therefore I am no longer writing data to the file. Anybody can help me? Thanks! BTW it never stops at the same place. I can sometimes receive 2K but other times I can receive a lot more. The most I got was 94,168 bytes. -- modified at 13:41 Tuesday 6th February, 2007
jpyp
One other question - Are you pausing your app's main (user interface) thread anywhere, with Sleep() or a loop? This will prevent the necessary message handling by CSocket which it relies on to make the OnReceive() call. Mark
-
One other question - Are you pausing your app's main (user interface) thread anywhere, with Sleep() or a loop? This will prevent the necessary message handling by CSocket which it relies on to make the OnReceive() call. Mark
I found the problem. Whoa! Thanks Microsoft! The following link fixed it. It seems to be just a band-aid solution but it will do until I go to high-transfer of data. Look for the reply "fixed" in red. http://www.codeproject.com/internet/ndk.asp?df=100&tid=487745&forumid=1156&exp=1&mpp=50&select=487745#xx487745xx Thanks anyway Mark!
jpyp
-
I found the problem. Whoa! Thanks Microsoft! The following link fixed it. It seems to be just a band-aid solution but it will do until I go to high-transfer of data. Look for the reply "fixed" in red. http://www.codeproject.com/internet/ndk.asp?df=100&tid=487745&forumid=1156&exp=1&mpp=50&select=487745#xx487745xx Thanks anyway Mark!
jpyp
Cool! That's a good one :) When you go to higher tranfer rates I'd recommend using CAsyncSocket and/or Sockets APIs and using WSAEventSelect instead of WSAAsyncSelect. Much better performance and you have complete control over the events. You can either a) recv() until there's no more data and go back to waiting for an FD_READ event, which will occur when more data is in the socket's receive buffer. Or... b) recv() a certain amount of bytes and go back to waiting for an FD_READ event. If more bytes are available for receiving then the FD_READ event is set immediately after the last recv() call. Thank you for the update! Mark
-
I found the problem. Whoa! Thanks Microsoft! The following link fixed it. It seems to be just a band-aid solution but it will do until I go to high-transfer of data. Look for the reply "fixed" in red. http://www.codeproject.com/internet/ndk.asp?df=100&tid=487745&forumid=1156&exp=1&mpp=50&select=487745#xx487745xx Thanks anyway Mark!
jpyp
The basic advice is that you should make exactly one single call to Receive (which calls the underlying winsock recv() function) from inside your OnReceive function (which the MFC framework calls in response to an FD_READ notification). This advice can't be found in the MFC documentation, either for CSocket or for CAsnycSocket. It's found, however, in the documentation for the underlying Winsock functions. For example, see the documentation for WSAAsyncSelect() (which is the Winsock function that causes Windows-style messages to be posted to your application from the network stack) at http://msdn2.microsoft.com/en-us/library/ms741540.aspx[^], which includes this quote:
MSDN at WSAASyncSelect wrote:
With these semantics, an application need not read all available data in response to an FD_READ message — a single recv in response to each FD_READ message is appropriate. If an application issues multiple recv calls in response to a single FD_READ, it can receive multiple FD_READ messages. Such an application can require disabling FD_READ messages before starting the recv calls by calling WSAAsyncSelect with the FD_READ event not set.
The point of this is to suggest that you get closer to the Winsock API when you start programming for high-rate transfers. There a a few dozen of these "gotcha's" that you don't learn/know about when using the MFC classes, particularly the CSocket class. Personally, I would avoid CSocket. CAsyncSocket is fine, since it's reasonably close to the Winsock API, but you still need to understand the underlying API if you expect your program to work correctly. Mike
-
The basic advice is that you should make exactly one single call to Receive (which calls the underlying winsock recv() function) from inside your OnReceive function (which the MFC framework calls in response to an FD_READ notification). This advice can't be found in the MFC documentation, either for CSocket or for CAsnycSocket. It's found, however, in the documentation for the underlying Winsock functions. For example, see the documentation for WSAAsyncSelect() (which is the Winsock function that causes Windows-style messages to be posted to your application from the network stack) at http://msdn2.microsoft.com/en-us/library/ms741540.aspx[^], which includes this quote:
MSDN at WSAASyncSelect wrote:
With these semantics, an application need not read all available data in response to an FD_READ message — a single recv in response to each FD_READ message is appropriate. If an application issues multiple recv calls in response to a single FD_READ, it can receive multiple FD_READ messages. Such an application can require disabling FD_READ messages before starting the recv calls by calling WSAAsyncSelect with the FD_READ event not set.
The point of this is to suggest that you get closer to the Winsock API when you start programming for high-rate transfers. There a a few dozen of these "gotcha's" that you don't learn/know about when using the MFC classes, particularly the CSocket class. Personally, I would avoid CSocket. CAsyncSocket is fine, since it's reasonably close to the Winsock API, but you still need to understand the underlying API if you expect your program to work correctly. Mike