Thread: sending on tcp

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    8

    sending on tcp

    Hello,
    I've set up a tcp connection. I'd like to send an int over tcp.
    Can you help me to do that ?
    I've tried this, it doesn't work :

    client
    int i = 0;
    send(sock, &i, sizeof(i), 0);
    server
    int i ;
    recv(sock, &i, sizeof(i), 0);

    I'd also like to send a structure. I think the client part is ok, but I'm having problems with the server.
    My struct is composed of a char and a char[256] (I know, it's not very clever but I'm just trying to understand how it works).
    here is what i did :
    structure s;
    recv( ear, &s, sizeof( structure ), 0 );

    apparently s.char is received, but s.string acts weirdly : when I print its characters one by one, I find out that the string I sent only appears on the 4th char.
    Do you see why this is, and how to fix it ?

    Thanks

  2. #2
    Registered User
    Join Date
    Mar 2010
    Posts
    8
    Nobody knows what's wrong ?

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    There's nothing wrong with the bit of code you posted (except that it's not really portable). So, no, nobody knows what's wrong.

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    8
    What do you mean there's nothing wrong ?
    There is obviously something wrong since my string only appears on the 4th char instead of the first one... unless you can explain to me why I need to add 4 to make it work...

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by jamesford View Post
    What do you mean there's nothing wrong ?
    There is obviously something wrong since my string only appears on the 4th char instead of the first one... unless you can explain to me why I need to add 4 to make it work...
    I'm not saying your code isn't wrong. I'm saying the code you posted isn't wrong. So no, I can't explain to you why your program doesn't work if you post only a (more or less) valid part of the program.

  6. #6
    Registered User
    Join Date
    Mar 2010
    Posts
    8
    ok, but I don't think I can send it all, there's just too much to send. Is this enough to see what's wrong (I mean, there's nothing wrong per say, but it doesn't work if I remove the '+3', though I don't know why it's here, and I'd like to know if you do).
    Code:
    typedef struct
    {
    	REQUEST request;
    	char fileName[MAX_NAME_LENGTH];
    } message;
    server :
    Code:
    void receive_mess( SOCKET ear, message* p_mess, REQUEST* p_req, char name[MAX_NAME_LENGTH] )
    {
    	 recv( ear, p_mess, sizeof( message ), 0 ) ;
    	*p_req = p_mess->request ;
    	strcpy( name, p_mess->fileName + 3 ) ;
    }

    client :
    Code:
    void send_message( SOCKET sock, REQUEST req, char name[MAX_NAME_LENGTH] )
    {
    	message mess;
    	mess.request = req;
    	strcpy( mess.fileName, name );
    	send( sock, &mess, sizeof( mess ), 0 ) ;
    }

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Hmmm I can't see anything wrong immediately. But you might be compiling both server and client differently. Just out of interest, try to print this in both client and server and see if they match:
    Code:
    ((int)((message*)0)->fileName)
    If they match, then either I'm missing something or you send three bytes before you call to this function, or something entirely else is wrong.

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you do not check return values of send/recv

    tcp does not guarantee to transfer the whole buffer at once
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User
    Join Date
    Mar 2010
    Posts
    8
    Where exactly am I supposed to print this ?
    Like this ?
    void receive_mess( SOCKET ear, message* p_mess, REQUEST* p_req, char name[MAX_NAME_LENGTH] )
    {
    recv( ear, p_mess, sizeof( message ), 0 ) ;
    *p_req = p_mess->request ;
    strcpy( name, p_mess->fileName + 3 ) ;
    printf(%s, ((int)((message*)0)->fileName) );
    }

    Code:
    void send_message( SOCKET sock, REQUEST req, char name[MAX_NAME_LENGTH] )
    {
    	message mess;
    	mess.request = req;
    	strcpy( mess.fileName, name );
    printf(%s,      ((int)((message*)0)->fileName)     )
    	send( sock, &mess, sizeof( mess ), 0 ) ;
    }

    vart, I actually tested for -1 and raised an error if it matched. But I don't understand your comment regarding the buffer. Do you mean that I could retrieve this error and send what hasn't been sent, without quiting the program ?

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    @vart: You're right, but I highly doubt that is the problem in this case.

    And you can put that piece of code anywhere. Though the field is an integer, so use %d to print it. It basically prints the number of bytes in the structure before "fileName". I know it's not portable, but for debugging it works.

  11. #11
    Registered User
    Join Date
    Mar 2010
    Posts
    8
    Yes you're right, it works with %d and not %s, though I don't understand why, as s->filename is a char* ...
    Anyway, you're right, they don't give the same result : the client returns 4 but the server returns 1...
    It seems you found out the problem. Can you explain it to me now ?

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by jamesford View Post
    Yes you're right, it works with %d and not %s, though I don't understand why, as s->filename is a char* ...
    Anyway, you're right, they don't give the same result : the client returns 4 but the server returns 1...
    It seems you found out the problem. Can you explain it to me now ?
    DAMN I'm good .
    There's a lot more wrong with your code, though, so you should fix a lot. Eg. check the recv/send return codes and whatnot. Also, reading directly to a struct and sending from a struct is actually kind of wrong, though used very often.

    Anyways, the problem in this case... You send the data from the structure and you read it into the other structure. This means both structures must have EXACTLY the same format in both client and server. But apparently it does not: the relative address in one is 4 and in the other 1.
    So the problem is the classes aren't the same. This can have two reasons I can think of. First, it might mean the structure "REQUEST" aren't identical in client and server. In that case, obviously, you can't copy it verbatim. You can test this by printing sizeof(REQUEST) in both client and server. If they're different, then the REQUEST structures are different.
    It might also mean the client and server are set to pack the structures differently. See, a structure with one char might be padded by 3 useless bytes to speed up the processing at the cost of memory. But it might be configured not to add this padding at one, and add it at the other.
    How you configure this "packing" depends on the compiler and I never do it, so I'm not sure how it's done (I refuse to use these details in my application). What compiler are you using?
    Look if one of the programs has something like "#pragma pack" or similar.

    And how the line works... It's prints the integer value of the pointer should the entire structure be at address 0. Actually printf with "%p" was probably better, but this was easier for me.

  13. #13
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    to avoid such problems I would convert struct to string and send a string buffer, parsing it on the over side and filling the struct

    Code:
    char buffer[1024];
    int len = sprintf(buffer, "%04d,%04u,%s", mess.request, strlen(name),name);
    send(buffer,len...);
    and on server - recv 10 bytes of req code and name len, parse it
    using sscanf for example and then recv the name
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #14
    Registered User
    Join Date
    Mar 2010
    Posts
    8
    okay, thanks for these explications. (I'm using gcc).

    You're right I just checked the structure lengths and there's a difference of 3 Bytes between them. I really don't understand why, there are defined the very same way, and on the same computer... Can you see why this is ?

    I am also interested in fixing my code, so what exactly is wrong with it ? (I'd rather not send structures as char*'s if possible).
    I have actually checked for -1 return values and I have raised an error (perror + exit(errno)) if it matches.
    What else should I do ?
    I've heard of serialization, but I don't really understand what it is (in spite of having read wikipedia), nor do I know how to implement it. Can you help me with that ?

    thanks.

  15. #15
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Make it pack the structure, like this:
    Structure packing with the GNU C compiler

    I have no idea why one structure would be packed and the other wouldn't, though. Maybe there's some "pack the following structures" directive in one of the headers files you include in one, but not the other.
    Otherwise google "structure packing".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sending / Receiving Info Via TCP or UDP
    By bengreenwood in forum C Programming
    Replies: 0
    Last Post: 03-24-2009, 02:17 AM
  2. sending zero bytes over TCP socket
    By nantonop in forum Networking/Device Communication
    Replies: 4
    Last Post: 09-03-2007, 08:10 AM
  3. sending TCP reset
    By netranger in forum Networking/Device Communication
    Replies: 3
    Last Post: 08-07-2007, 10:09 PM
  4. Accessing TCP flags in TCP packets on Linux using C !!
    By vishamr in forum Linux Programming
    Replies: 2
    Last Post: 10-16-2006, 08:48 AM
  5. SSH Hacker Activity!! AAHHH!!
    By Kleid-0 in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 03-06-2005, 03:53 PM