Advanced winsock questions.

Okay so i setup a non blocking winsock socket with WSAsyncselect and it works and i can receive data from client without errors on either side. I setup error checking and messagebox after almost every winsock execution so i know what is doing what.

first...Ignoring the connection since it works here is my problem. With winsock all data is not sent at once. Nor is all data sent received at once. So 100 bytes may be sent....but even then the receiving end may only receive 70 bytes....if my understanding is correct. If all data is not received in first execution will it be held internally in the socket then be received next execution??

Second....I need to setup a nonblocking socket on the client end. I simply can't poll the socket and miss receiving data. Blocking sockets have to be one of the useless things ever designed. Would it be as simple as setting up a non-blocking socket on client side using WSAAsyncSelect() to communicate with server non-blocking socket.

third....in the sending and receiving buffer i have some questions. In the receiving buffer every time data is received is it written from the beginning of the buffer..."buffer[0]" so it simply overwrites what was previously received? I'm pretty positive it does this.

So back to the first problem. In the message handling WSASELECTEVENT param i have the FD_READ, FD_WRITE, FD_ACCEPT ect. Going back to my previous statement that all data that is sent may not be received you would have to implement an "ack" or an acknowledgement that is sent back to the sender to tell how much data was actually received out of the sent data....that way sender can resend data that was not received.
This code does not implement that yet because im simply concerned with being able to send and receive multiple chunks. Acknowledgements and seperate indications socket will be implemented in future (prolly a couple days).

With all winsock you have to piece together received data. I receive it on server side in buffer[] array and piece it together in tempbuffer[] array after each time data is received.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

switch ( WSAGETSELECTEVENT ( lParam ) )
			{	// What happened, exactly?
                case FD_CLOSE:
                     MessageBox(NULL, "Connection was aborted..client left", "socket indication", MB_OK);
                     break;
				case FD_READ:
                   /*  Sleep(10); */
                //Incoming data; get ready to receive
                
                nret = recv(theClient, buffer, 51,	0);
                if (nret <= 0)
	            	{
			             MessageBox(NULL, "recv() returned nothing.", "socketIndication", MB_OK);
		              }
		         if (nret >=0) 
		              {
                           isMovingleft=true;
                           MessageBox(NULL, "Data has successfully been received!", "socket indication", MB_OK);
                           HandleBufferServer(nret); 
                           }
                           
               
                 break;
/*this simply copies received buffer to a Tempbuffer...that way data received in pieces will be put together fully in tempbuffer. It iterates through each buffer with a while loop. */
void HandleBufferServer(int BytesReceived)
{    
     TotalBytesReceived=TotalBytesReceived+BytesReceived;
     BufferShiftPos=TotalBytesReceived;
     ShiftComplete=false;
     while (!ShiftComplete)
     {
           TempBuffer[BufferShiftPos]=buffer[i];
           i++;
           BufferShiftPos++;
           if (i>=nret)
           {
           //clear the buffer for future receives then set ShiftComplete to true to exit shift loop
           
           ShiftComplete=true;
           MessageBox(NULL, "server shift complete", "Shift Indication", MB_OK);
           i=0;
           }
           if (TotalBytesReceived>=30)
           {
           //All data for this specific data set has been received.  Set TotalBytesReceived to 0 so future receives will not be cut short...use totalbytesReceived array to receive multiple data sets simultaneously

           TotalBytesReceived=0;
           MessageBox(NULL, TempBuffer, "Complete Buffer Received", MB_OK);
           }
           }
}


But with this code since it is a non blocking socket if more data is received before the shift is complete (see the code for what i mean) then all the received data will not be transferred and correctly placed and peiced together in the TempBuffer[] array before buffer is rewritten with new data received.

on my client side...which isn't nonblocking i simply send out a buffer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 while (!ChunkSent)
{
                         if (!bufferInit)
                         {
                         strcpy(buffer, "This is a test buffer that will contain a rather long buffer of char's to be sent.  It is less then the buffer size");
                         bufferInit=true;
                         }
                         Sleep(1);
                         MessageBox(NULL, buffer, "data contained", MB_OK);
                         Size=strlen(buffer);
                         nret=send(theSocket, buffer, strlen(buffer), 0);
                          if (nret==SOCKET_ERROR | nret<=0)
                         {
                                MessageBox(NULL, "Send() returned socket error.", "Socket Indication", MB_OK);
                                }
                         if (nret>=0)
                         {
                                  TotalBytesSent=TotalBytesSent+nret;   
                                  MessageBox(NULL, "Data has been sent from client" , "Send loop notification", MB_OK);
                                  HandleBufferClient(nret);
                         }
                         if (TotalBytesSent>=40)
                         {
                         MessageBox(NULL, "complete chunk has been sent" , "Chunk sent", MB_OK);                       
                         ChunkSent=true;
                         
                         }

}

void HandleBufferClient(int BytesSent)
{    
     ShiftComplete=false;
     TotalBytesSent=TotalBytesSent+BytesSent;
     BufferShiftPos=TotalBytesSent;
     //clear buffer then copy remaining buffer mask to buffer starting at 0....send whole buffer.
     while (!ShiftComplete)
     {
           TempBuffer[BufferShiftPos]=buffer[i];
           i++;
           BufferShiftPos++;
           if (BufferShiftPos>=Size)
           {
           ShiftComplete=true;
           MessageBox(NULL, "Client shift complete", "Client Indication", MB_OK);
           }
           }
}


Humurously enough i copied the message to be sent to buffer then stored it into the tempbuffer as if i was sending tempbuffer. I need to fix that before i get this working. But it sends out data find and i get my message box popping up saying data was sent successfully. On receiving end i get message box saying data was received correctly....But when it displays the received message it is empty if i try to display text stored in tempbuffer[]. If i just store text in buffer then display message box with buffer[]'s text then it displays the same text each time. It displays some of the middle text and thats it.

I need to make my sending code where it iterates the next text in the buffer to be sent into the tempbuffer then sends the tempbuffer. So if it sends 6 bytes it will then iterate through the buffer array starting from the 6th "[6]" array value and store the rest of the array into Tempbuffer[] then null terminate the empty arrays in tempbuffer so last data sent will not be sent with it.

However with arrays you cannot dynamically allocate array memory unless if you use the new function...but that is messy. Also it would probably be tough to send binary array's meaning it would be hard to send binary files.


Last edited on
Also...I need to implement multiple sockets on each client server that are non-blocking and have server to server communication. I'm thinking i would just loop through each socket assuming i had a socket array and use semi sql statements to find socket array number by a username. I'm thinking that having multiple sockets would let data be missed if it is trying to recv() data from an incorrect socket then what data was truly sent from. But it must work since online games have millions of players.

Then based on the size of data being manipulated as it is recv'd i plan on having a function run that will estimate how long it will take to handle operations on that data. Then it will send back this estimate plus a slight extra back to sender as an Acknowledgement and a command to pause sending data until it has time to handle the data it has already received. Or i will simply have it handle the data then send out an ack when it is ready to receive more. This way more data won't be recv'd until previous data has been correctly handled.
Last edited on
Topic archived. No new replies allowed.