Getting strange characters / characters in winsock

I find out that Winsock and Im have a weird problem sending and receiving a simple string. Here's my code (pure C):

Customer:



//...
//Declarations and stuff

//----------- SEND SOME DATA -------------------------------------------------

    char string1[] = "string-1";
    int bytes_sent = 0;

    bytes_sent = send(client_socket, string1, strlen(string1), 0);  

    printf("BYTES SENT: %i\n", bytes_sent);
    printf("\n-----------------------------------------------\n\n");

    system("pause");

//...

      

Server:



//...
//Declarations and stuff

//----------- START LISTENING FOR REQUESTS ------------------------------------

    SOCKET ClientSocket;

    #define BUFFER_SIZE 256

    int size;
    struct sockaddr_in client_info;
    char client_ip[16];
    char data_received[BUFFER_SIZE];    
    int bytes_received = 0; 

    listen(ListenSocket, SOMAXCONN);

    while(1){           

        ClientSocket = accept(ListenSocket, (struct sockaddr *)&client_info, &size);        
        strcpy(client_ip, inet_ntoa(client_info.sin_addr));     

        do{

            bytes_received = recv(ClientSocket, data_received, BUFFER_SIZE, 0);

            if(bytes_received > 0){
                printf("DATA RECEIVED FROM %s: %s (%i bytes)\n", client_ip, data_received, bytes_received);
            }


        }while(bytes_received > 0);

        printf("\n-----------------------------------------------\n\n");


    }

//...

      

The problem is the server is printing my string + some weird characters (see pic).

Strange symbols

Im using a streaming socket. The example is very simple, so I don't know what might be wrong. The problem goes away (the server prints out the line OK) if I arbitrarily change the line or the server buffer size, or both. The problem is fixed if I use sizeof () instead of strlen () in the send () call. I'm a little lost here. Please be kind if I missed something, this is my first post here. I can provide all the code (its basically a winsock start and a socket definition).

+3


source to share


3 answers


The data you are sending does not contain a terminating null character:

bytes_sent = send(client_socket, string1, strlen(string1), 0);

      

... because it strlen

doesn't count trailing zero. This is not really a problem in itself, but rather has to do with the fact that on the receiving end:

char data_received[BUFFER_SIZE];
// ...
bytes_received = recv(ClientSocket, data_received, BUFFER_SIZE, 0);

      

data_received

is not initialized and you can get up to BUFFER_SIZE

bytes. This means that since the data you sent is not null-terminated:

  • If bytes_received < BUFFER_SIZE

    , the rest data_received

    may not be initialized, so print access will be undefined. In fact it is not 100% clear, as the documentation says:

    [...] calling recv will return as much data as is currently available, up to the size of the specified buffer [...]

    ... so it could mean that the rest of the buffer is left untouched.

  • If bytes_received == BUFFER_SIZE

    , then there is no null terminator, so printf

    will cause undefined behavior trying to print it, since it doesn't know where the string stops and will exceed the array.


The easiest way to fix this is to either send a null terminator:

bytes_sent = send(client_socket, string1, strlen(string1)+1, 0); // +1 here
bytes_sent = send(client_socket, string1, sizeof(string1), 0);   // same as above

      

... or get less than a byte and put a null terminator on the receiver size:

bytes_received = recv(ClientSocket, data_received, BUFFER_SIZE-1, 0); // -1 here
data_received[bytes_received] = 0;

      

I personally would go first.

+7


source


So the problem is that you are not sending the terminating NUL

byte, but you seem to be treating the resulting string as a C string (that is, you assume it is NUL terminated). To fix this, instead of

bytes_sent = send(client_socket, string1, strlen(string1), 0);

      

records



bytes_sent = send(client_socket, string1, strlen(string1) + 1, 0);

      

Also, you mentioned that "nobody is using strlen(s) + 1

" - perhaps because they pay attention to the number of bytes received on the receiving end.

+2


source


Try to set the length of all your string data and then terminate the string on the server like this:

bzero(data_received, sizeof(data_received));
bytes_received = recv(ClientSocket, data_received, BUFFER_SIZE, 0);
data_received[bytes_received] = '\0';

      

If this doesn't work out, maybe @ H2CO3 can help you know better what you ask:]

-1


source







All Articles