Skip to main content
gamedev.net
🔒 Locked

winsock (hopefuly) basic problem

Started by nef123 Apr 18, 2009 at 5:32 AM 0 replies 1k views
Original Post
nef123
nef123
Hello, im trying to send larger chunks of data in c++/winsock/TCP. I read a couple of tutorials, so i thought i had all the theory, but seemes i do not. Here are my test subjects, can anyone help me identify the problem? (seems to be something with how the winsocks work rather than my code, so i wont post much code for now). Im using that windows notification type of socket where you wait for winsock message in windows message pump. Everything works for small chunks of data and that which are sent in long time intervals. Problems are: 1) When i use send call, and give it 4000+ byte long char array (possibly shorter too), the client never gets anything. I tested it in debug mode to see if at least windows notifies the reciving program, as i suspected that at least some part of it should arrive and give the notification. But nothing. window's Message processing function does not even get any event of this. 2) When sending couple of smaller packets (around 1000 byte) i usually recive either first one x 1000, or first two x1000 (joined together). Separating them is no problem. I have set up a mechanism for this, that for example if i have 16,000 bytes to send, i send first 1000 with additional information about total (16,000) size, and next 15,000 i send normally calling send (even waiting 100ms before each call just in case). On the reciving machine when i get the first part, i check the total length, and if the already recived part + the previous recived parts are shorter i enter a loop where SELECT function waits for more data. But neither more data nor another windows notification ever arrives... With that "expecting 16,000" and "do SELECT(...); recv(...) while (recived // ...windows message pump switch (WSAGETSELECTEVENT(lParam)) { // Differentiate between the events char tmp[4096]; char buf[4096]; case FD_READ: { int expecting=4096;//temporary ammount untill expecting real value is determined bool expect_read=false; int totBytesRead=0; do { waitUntilSocketIsReadable(socketToServer,SOCK_ToServer);// first parameter is of type SOCKET, second one is windows event message (WM_USER+1) int bytesRead = recv(socketToServer, tmp, 4096, 0); if (bytesRead < 0) break; tmp[bytesRead]='\0'; if(expect_read==false){ expecting=reconstructPrefix(tmp);//here first bytes are taken to get the expecting value from recived data expect_read=true; strcpy( buf, tmp); } else{ strcat(buf, tmp); } totBytesRead += (unsigned)bytesRead; } while (totBytesRead < expecting+2); //process the fully read data break; //------------------- // function that waits for more data //------------------- void waitUntilSocketIsReadable(SOCKET socket, int soc){//int socket){ fd_set rd_set; FD_ZERO(&rd_set); //FD_SET((unsigned)socket, &rd_set); FD_SET(socket,&rd_set); struct timeval timeout; timeout.tv_sec = timeout.tv_usec = 0; int result = select((unsigned)(soc), &rd_set, NULL, NULL, NULL);//;&timeout); <-- tried with timeout NULL, and timeout 0. } With this i get only 1000 or 2000 first characters. P.S. I know the buffers are at 4096, and im expecting 16,000. But i dont get anymore than 2000, so its not the issue here. EDIT: To put it simple. I dont get separate notifications on reciver for each send from server. So i thought that by waiting with "select" function i will recive the rest of data that is still being transmitted after first notification. But it doesnt seem to work like that. EDIT2: Is there any other way to solve this than sending "OK" message after reciving each 1k block? I thought sending ACK was kind of automatic, and i should only send data, without waiting for response messages from client, as this is dealt by TCP protocol. edit: newlines and CODE blocks. [Edited by - hplus0603 on April 18, 2009 4:10:38 PM]
hplus0603
hplus0603
Using asynchronous sockets with messages through WinSock is known to have problems. The most important problem is that you should not call WinSock from within an FD_READ or FD_WRITE notification (!) Instead, you should set a flag of some sort, and check that flag up at the top level loop of the program.
enum Bool { True, False, FileNotFound };

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.