windows sockets (WINSOCKS) problem

Pages: 12
Good Am/Pm,

I'm currently creating a client server application and I'm using Visual Studio 2005 and Microsoft Windows. I've been using this WINSOCK API for creating my application. I've been able to communicate and send data from my client to my server, the problem is I can only send characters and strings.

My aim is to send a 640x480 array which contain floats from my client to my server. It seems that the recv() and send() functions output are characters.

I need your help, a sample code to send a simple integer or 2x2 array to be sent will be a lot help.

Thanks

Robbie

you can send anything, just cast it to required format. and in the server again cast it back. it will work.
if the array is big, you may need to send it in chunks and the server should be intelegent enough to understand how much data you are sending.

see this:

client sending this structure to server:
nSend = send(ClientSocket,(TCHAR*)&xi,sizeof(XINFO),0);

xi is of type xinfo, which is like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct xinfo
{
	HWND		hTree;						//which tree this structure point to
	SOCKET		SockInfo;					//which socket sending data
	INFOTYPE	infotype;					//what info, like adding root, child etc.
	FILETYPE	filetype;					//what kind of node is this
											//directory,file,remote,cdrom etc.
	DWORD			nRead;					//How much data send
	DWORD		dwSize;						//File size
	
	TCHAR		szFolderPath[MAX_PATH];		//path of remote folder
	TCHAR		szFileName[MAX_PATH];		//name of remote file/folder

	TCHAR		szBuffer[READ_BUFFER];
	

}XINFO;


now recv it at server side like this:
1
2
XINFO				xi;
nRecv = recv(ClientSocket,(TCHAR*)&xi,sizeof(XINFO),0);


I hope this will help, you can see i have send tchar's, dword's and other types even a structure inside a structure (INFOTYPES).

Last edited on
Hi writetonsharma,

Thank you for your quick response, i'll try this immediately. I'll be posting updates, thank you so much !

Robbie

Good Am/Pm,

I am able to send integers however.. i cant seem to receive them right.. i'm sending an 2x2 array. Right now the client said that it was able to send the data.

I'm using a for loop for sending..

sending sample code:
for(m=0;m<2;m++)
{
for(n=0;n<2;n++)
{
printf("sendbuf[%d]; ",x);
printf("data[%d][%d] = %d",m,n,data[m][n]);
itoa (data[m][n],sendbuf,10);
printf("sendbuf %s \n",sendbuf);
BytesSent = send(SendingSocket, sendbuf, strlen(sendbuf), 0);
}
}

so now i'm converting integers to char using itoa and sending it.. and receiving them as char and converting it back to int.

receiving code:
for(m=0;m<2;m++){
for(n=0;n<2;n++){
ByteReceived = recv(NewConnection, recvbuff, sizeof(recvbuff), 0);
intrecv[m][n] = atoi (recvbuff);
printf("DECIMAL VALUE IS %d \n",intrecv[m][n]);
}
}

the problem is that in the receiving end sometimes for example if i send the number "200" then the number "1" it receives it as "2001" the server combined the 2 data and saved it as one..

does anyone have an idea on how am i going to program the server that after receiving a certain integer it will store it immediately and not receive another one then store them both at the same time.

Thanks,
Robbie
Network programming isn't quite the same as file I/O.

The number of client sends doesn't tie up with the server receives. TCP or UDP just sends blocks of bytes. Futher more, a router is free to split the packets into smaller manageable. In general, you need to check the return value from recv and build up the buffer until you have all the data you expect.

Your receive code should:
1. create a buffer large enough to hold your return data.
2. receive the data, looping as necessary to fill the buffer.
3. reinterpret the byte stream as the type you sent and use it.
Last edited on
Thanks you kbw for you're reply..

i really new at network programming..

so what you're saying is that i should accept the data as a whole? accepting all the sent data first before i interpret it? am I right?

correct me if i'm wrong but this is how i understand it.

if i send the array {23,45,678,90} same as my code before converting it to char 1st before sending it because the send function only send char..

the receiver will receive something like this. "234567890".. thus i'm suppose to reinterpret that..

umm... i have no idea how to do that..

more tips please.. tips and advices anything anyone can give?

Thanks so much,
Robbie
Your send code is sending zero terminated char arrays. So the server doesn't know how much to read. If you want to send an array of integers, your code could be:
1
2
3
4
5
for(int i = 0; i < mxi; ++i)
    for (int j = 0; j < mxj; ++j)
    {
        send(s, (char*)&data[i][j], sizeof(int), 0);
    }


The receiver would be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (int i = 0; i < mxi; ++i)
    for (int j = 0; j < mxj; ++j)
    {
        int value = 0;
        int nbytes = recv(s, (char*)&value, sizeof(int), 0);
        if (nbytes == -1)
        {
            std::clog << "recv: error" << std::endl;
            return nbytes;
        }
        else if (nbytes != sizeof(int))
        {
            std::clog << "recv: unexpected fragmentation" << std::endl;
            return nbytes;
        }

        std::cout << i << ":" << j << " = " << value << std::endl;
    }


I've assumed the 4 byte block isn't going to be fragmented. I've assumed the hardware have the same endian characteristics.
Thank you kbw,

I'll be adding this error checking method in to my code.. another question, in the code you just showed me.

You also used the recv() function as many times at you used the send() function, am I correct?
Meaning for ever send() there is a corresponding recv()?

Thanks,
Robbie
In that example, yes. That's because I'm sending/receiving 4 bytes at a time, which is a very small payload that is unlikely to be fragmented, and mostly to provide you with some sample code.
okey thanks again kbw.. ^_^

Robbie
was on a long holiday.. :P
so were you able to solve your problem.
Hi Guys,

@writetosharma
Yup, I have solved my problem. Thanks so much for your help.^_^ but I have another problem regarding sockets.

@Everyone

An update on my project..

I'm having different problem.. I cant seem to receive all the data sent by my client.

Client Code:

sz=sizeof(FinalImage1);
send(SendingSocket,(char *)&sz,sizeof(int),0);
Bytesent=send(SendingSocket, (char*)&FinalImage1, sz, 0);

Server Code:
recv(NewConnection,(char *)&sz,sizeof(int),0);
ByteReceived = recv(NewConnection,(char*)&testimage, sz, 0);

the FinalImage1 is a [720][480] array and thus the send buffer turns out to be around 600kb when i use sizeof. So I am expecting to receive a 600kb data to the server.

The problem is when I view the return in the send function it value is -1.
So that means I just sent -1 number of bytes? or is does this mean that I got an error in the send function? If so i assume I sent to much data in one send function that why I got an error?

If I where to divide my data to smaller packets, how do I do that? Do I use for loop?
and is there a limit on how much data can I send in one send() function?

I need to transfer this 720x486 array to the server.

Help please..


Thanks,
Syncopath
Last edited on
That's a lot to attempt to send in one go. Try sending 16k chunks at a time.
@kbw
Thank you for your quick reply. ^_^

Mind if I ask on how am I suppose to do that? I'm thinking that I should be using pointers? But I don't know how to do that just yet.

If I where to use for loop like so..

for(int i = 0; i < mxi; ++i)
for (int j = 0; j < mxj; ++j)
{
send(s, (char*)&data[i][j], sizeof(int), 0);
}

like your previous example. I would be sending about 8bytes per send if I where sending doubles right? so how am I going send chunks at a time. for example 16k chucks?

I tried to use that for loop style before.. I send one double per send and repeated it for like 600k times but in about 10k or less my pc crashed. so i guess I should not be using this kind of technique. I should be sending data in huge chucks but I don't know how to do that. I'm still reading on pointers right now.

Help please.. any examples or tips are surely to be appreciated.

Thanks,
Robbie
Use a single loop:
1
2
3
4
5
6
7
8
9
10
for (char* p = FinalImage1, end = data + sizeof(FinalImage1); p < end; )
{
    int blocksz = std::min(16*1024, end - p);

    int sent =  send(s, p, blocksz; 0); // corrected, the block to send starts at p
    if (sent <= 0)
        break;

    p += sent;
}
Last edited on
@kbw

Thank you again for the quick reply.

So "p" and "end" are pointers, right?
if I understand this correctly, the loop will continue until the value of "p" is equal to "end"?

and blocksz returns the value which is lesser from 16*1024 and "end-p" thus, choosing which is lesser to be the size for the send function.


this is just for error checking, right?
------------------
if (sent <= 0)
break;
------------------

and I get it that the value of sent is added to the begin.


My question is, what is "data" and why is end=data + sizeof(FinalImage1)?
I'm assuming "data" is also "sizeof(FinalImage1)"?

and the second value in the send() function is suppose to be the data right? I don't know what to put there?
"begin" is an undeclared variable. should I put "FinalImage1" there or "p"?

I'm really confused, I'm new in using pointers. Forgive me for the questions.

Thanks,
Robbie

Last edited on
I've formatted the code.

It assimes the data to be sent is in a fixed variable called FinalImage1, which I got from your code above. The code loops sending the next chunk each time until it's all gone.
@kbw

Thank you so much. I'll be try this out and posting updates soon

Regards,
Robbie
Hey Guys,

I've been having problems with the server side:

Server Code:
recv(NewConnection,(char *)&sz,sizeof(int),0);
ByteReceived = recv(NewConnection,(char*)&testimage, sz, 0);

So now I have multiple send() functions occurring because of the loop, my client is sending small packets. 1st my client is going to send the size of the whole data which is "sz" the it will now send the multiple small packets.

what happening now is i'm using just one recv() with a large buffer to accept the multiple small send().

The problem now is my server stops receiving packets even if the client is not yet finished sending.

Help please...

Thanks,
Robbie
Are you checking recv return codes?
Pages: 12