Find the answer to your Linux question:
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.
  1. #1
    Just 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

  2. #2
    Linux 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"

  3. #3
    Just 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

  4. #4
    Linux 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)

  5. #5
    Linux User
    Join Date
    Jul 2004
    Location
    Poland
    Posts
    368

    Re: Buffered sockets...

    Quote Originally Posted by burnit
    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.
    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.

    Quote Originally Posted by burnit
    Probably the second recv fails because the client has already executed the close on the socket.
    As far as I know, if connection has been closed by remote host, recv() should return zero.

    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"

  6. #6
    Just Joined!
    Join Date
    Sep 2005
    Posts
    5

    Re: Buffered sockets...

    Quote Originally Posted by burnit
    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.
    hmm ... what Im trying to do is
    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

  7. #7
    Linux 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)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •