Results 1 to 7 of 7
Hi I am trying to do multiple send's, but the server only recives the first send and displays the second send as empty or garbage:
Client code: (C++ code in ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
- 09-29-2005 #1Just Joined!
- Join Date
- Sep 2005
- Posts
- 5
Multiple send() from Client to Server
Hi I am trying to do multiple send's, but the server only recives the first send and displays the second send as empty or garbage:
Client code: (C++ code in Windows 2000 Professional)
char ch[] = "AB";
char ch2[] = "w";
send(sd, ch, sizeof ( ch ), 0);
send(sd, ch2, sizeof ( ch2 ), 0);
Server code: (C code on QNXOS)
char buff[3];
char buff2[2];
int len1,len2;
len1 = recv(ns,&buff,sizeof( buff),0);
len2 = recv(ns,&buff2,sizeof(buff2),0);
printf("Data1: %s\n", &buff);
printf("Data1: %s\n", &buff2);
printf("Len1: %i\n", len1);
printf("Len2: %i\n", len2);
Output on Server:
Data1: AB
Data2: 2AB
Len1: 3
Len2: -1
NB: no idea how buff2 gets AB ... infact the 2 is followed by the degree symbol and then AB. [smart garbage] Also I have tried all the combination of printing as char,string, typecast to int.
Another intersting thing is if my second send() at client: --
send(sd, ch2, sizeof ( ch2 ), 0); is replaced by
send(sd, ch2, 1460, 0);
the server in that case does show correct output. NO Code was changed at server side. Only the send at client was changed.
Any ideas at this weird behaviour and possible solutions are welcome.
Thanks
- 09-30-2005 #2Linux User
- Join Date
- Jul 2004
- Location
- Poland
- Posts
- 368
Could you send full code?
"I don't know what I'm running from
And I don't know where I'm running to
There's something deep and strange inside of me I see"
- 09-30-2005 #3Just Joined!
- Join Date
- Sep 2005
- Posts
- 5
Hi,
On the server side I found that for the second recv() it gives the following error message: "Connection Refused by Peer"
Thanks
- 10-01-2005 #4Linux User
- Join Date
- Aug 2005
- Location
- Italy
- Posts
- 401
Buffered sockets...
Some time ago, I've noticed that socket communications are buffered: if client performe two consecutive send, the server could receive all data sent in only one recv.
To resolve the problem I've added a special separator (for example ';' or '\n') between messages sent. In this way you should parse what recv returns.
Probably the second recv fails because the client has already executed the close on the socket.When using Windows, have you ever told "Ehi... do your business?"
Linux user #396597 (http://counter.li.org)
- 10-01-2005 #5Linux User
- Join Date
- Jul 2004
- Location
- Poland
- Posts
- 368
Re: Buffered sockets...
This can happen, but since he's recv'ing only three bytes, the rest should stay in the kernel buffer and wait for next call to recv.
Originally Posted by burnit
As far as I know, if connection has been closed by remote host, recv() should return zero.
Originally Posted by burnit
Again, if the program is not very big, I opt for posting it to the forum"I don't know what I'm running from
And I don't know where I'm running to
There's something deep and strange inside of me I see"
- 10-05-2005 #6Just Joined!
- Join Date
- Sep 2005
- Posts
- 5
Re: Buffered sockets...
hmm ... what Im trying to do is
Originally Posted by burnit
1)Send a Command to the Server that I want to upload file
2) If I upload i do another send telling the size of the file
3) Last send to send the entire file bytes.
So in the case of Uploadding i need to do 3 sends()
And if i download.
1)Send a Command to the Server that I want to download file
2) Recv the file size or -ve if file not available
3) Recv the file bytes
So, 1 send and 2 recv
How would you advise doing this ??
Thanks
- 10-06-2005 #7Linux User
- Join Date
- Aug 2005
- Location
- Italy
- Posts
- 401
Protocol definition
Your problem is a communication protocol definition. Once you have defined this, everything should be easier.
If you need to upload and download files, the communication is composed by:
- a file request (both for upload and download)
- a server confirm (ensuring client to be able to continue communication)
- file data transfer (to server for upload, from server for download)
Now, you can send messages using plain text or using data coding: text messages needs to be parsed (for obtaining data) and needs to be composed, while data coding need no parsing (pratically you send struct variables). Some limitation: using text messages, their lengths are flexible (because each text message is terminated by a special character, so you read a message until reach that char), while using data coding, each message has a fixed size.
If you need to specify the filename to upload/download, text messages are flexible (because file path has a variable length), but you can use data coding preserving space for file path (for example 2048 chars).
Using text messages, a communication should appear like this:
- (client->server) DOWNLOAD <filepath>\n
- (server->client) FILE [AVAILABLE|UNAVAILABLE]\n
- (server->client) FILESIZE <filesize>\n
- (server->client) <filedata>
- (client->server) UPLOAD <filepath>\n
- (client->server) FILESIZE <filesize>\n
- (server->client) FILE [UPLOADABLE|UNUPLOADABLE]\n
- (client->server) <filedata>
Using data coding, a communication should appear like this:
/* Structure to request a download/upload */
struct _file_request_s {
char path[2048];
long size;
#define FILE_UPLOAD 0x01
#define FILE_DOWNLOAD 0x03
uint32_t flags;
} file_request_t;
/* Server confirmation */
struct _server_confirm_s {
/* Error handling */
char errdescr[1024];
int err;
} server_confirm_t;
For download:
- (client->server) send(file_request_t); (with path set, flags set to FILE_DOWNLOAD, 0 size);
- (server->client) send(server_confirm_t);
- (server->client) send(file_request_t) (with path set, flags set to FILE_DOWNLOAD, size set to file size);
- (server->client) <file data>
For upload:
- (client->server) send(file_request_t); (with path set, flags set to FILE_UPLOAD, size set to file size);
- (server->client) send(server_confirm_t);
- (server->client) <file data>
Some notes: this is my solution... everyone can find a better protocol handling. Text messages are more flexible also for server/client compatibility; you can also use flex package to generate C source for message parsing
(this should be sufficient, I don't think you'll need bison).
You can define also generic error messages (for example ERR <errno> <errdescr>\n).
You can also gain flexibility to data coding using a 4 byte code at the beginning of each message structure. Reading this code, you can know about the structure type (and so its size): in this way the client/server can send any type of message at any time
.
That's all, folks!When using Windows, have you ever told "Ehi... do your business?"
Linux user #396597 (http://counter.li.org)


Reply With Quote
