Sending and receiving strings over TCP socket separately

后端 未结 4 1336
难免孤独
难免孤独 2021-02-10 19:17

I have a TCP server and client, with an established socket. Let\'s say I have the following case:

SERVER:

char *fn = \"John\";
char *ln = \"Doe\";

char          


        
相关标签:
4条回答
  • 2021-02-10 19:24

    The right thing to do is to enclose the sent data with a header. So you would pass the size of the message, including the size of the message, then on the other side you can figure out how long the message should be.

    John is 4 chars, so you have the length, something like "0004John" then you would know when to stop reading. You may also want to add a command to the header, that is very common. So for instance, first name might be 1, and second name 2;

    "01004JOHN" for instance would be set in the buffer and sent.

    To do this, you add items to the buffer, then increment the insertion point in the buffer by the sizeof the values you added. You can use this to add many parts to the buffer. *Just be sure you dont overrun the size of the buffer.

    Remember these examples im giving are not correct, because you dont pass the string representation of the number, just the number, so it would be a long int 1, long int 4 and then chars, or unicode, either way, 4 characters.

    0 讨论(0)
  • 2021-02-10 19:30

    TCP is stream-oriented, not datagram-oriented. If it was the latter, your stuff would work great. You have the following options:

    • use SCTP
    • use UDP if you can afford losing reliability
    • separate the strings in a way you can work with, either by prepending a length tag or so or by adding a NUL byte for terminating each string.

    For the latter, you would just do send(*socket, buffer, strlen(buffer)+1, 0); for including the NUL which is here nevertheless, and the sender would repeatedly recv() and find a string terminator until it has found 2 strings.

    Note that you should take care with strcpy(): only use it if you are absolutely sure that the string you are writing to is ok.

    Your receiver does

    bytes = recv(*socket, buffer, sizeof(buffer), 0);
    buffer[bytes] = '\0';
    

    That is bad because, if the buffer is full, so bytes == sizeof(buffer) (which could happen in more complex situations), buffer[bytes] = '\0' writes beyond the buffer. SO use

    bytes = recv(*socket, buffer, sizeof(buffer) - 1, 0);
    

    and you can happily do

    buffer[bytes] = '\0';
    

    .

    0 讨论(0)
  • 2021-02-10 19:32

    First, when the client calls recv(*socket, buffer, sizeof(buffer), 0);, it will receive up to sizeof(buffer) characters (here, 512) from the network. This is from the network buffer, and has nothing to do with how many times send has been called on the server. recv does not look for \0 or any other character - it's a binary pull from the network buffer. It will read either the entire network buffer, or sizeof(buffer) characters.

    You need to check in the first recv to see if it has both the first and last name and handle it appropriately.

    You can do so either by having the server send the length of the strings as the first few bytes of a stream (a "header"), or by scanning the received data to see if there are two strings.

    You really need to perform checks whenever you call recv - what if the string is longer than 512 bytes? Then you need to call recv multiple time sto get the string. And what if you get the first string, and only half of the second string? Usually these two cases only happen when dealing with larger amounts of data, but I've seen it happen in my own code before, so it's best to incorporate good checks on recv even when dealing with small strings like this. If you practice good coding tactics early on you won't have as many headaches down the road.

    0 讨论(0)
  • 2021-02-10 19:50

    instead of sizeof(buffer) use strlen(fn); so it will transmit only the exact amount of bytes.. if you need null terminator together use strlen(fn)+1 but don't forget to concatenate null terminator with strcat()

    also if you send all the buffer size without cleaning with memset you'll also have rubbish along, so beware that..

    0 讨论(0)
提交回复
热议问题