mercredi 5 août 2015

Residual characters printed on stdout with socket communication


In a socket TCP communication, I have a server and a client. Both can read from and write to the socket.

The code is written in C and uses Linux system calls recv and write.

recv saves the received string in:

char message_array[2000];

Another array with the same dimensions is used as source for the write process.

After both the reading and writing process the following operation is performed, to clear all the array elements:

memset(&message_array, 0, sizeof(message_array));

Moreover, a fflush is performed on stdin and stdout at every write and every read process.

The server prints on its stdout what it writes and what it receives.

If I send small messages from both the terminals ("hello", "hi") even for several times (18-20), all appears to work correctly. But if I try to send longer messages (longer than 5 characters, but shorter than 2000!), the server side has some strange behaviour: it prints the message received from the client, but then it inserts a random number of the trailing characters of the previous messages. For example I have:

CLIENT MESSAGE: hello1
SERVER MESSAGE: hello2
CLIENT MESSAGE: hello3
SERVER MESSAGE: hello4 
CLIENT MESSAGE: some other characters5
SERVER MESSAGE: hello6
CLIENT MESSAGE: a long phrase 7
ters5

After several messages, the 5 characters ters5 from a previous message appear as trailing characters after the actual message, which was just a long phrase 7. Continuing the "conversation", other unexpected newline and "old" characters appears on the stdout of the server.

The code of the read and write routine is the following:

void *connection_handler_read(void *socket_read_desc)
{
    int read_sock = *(int*)socket_read_desc;
    int read_size;
    char remote_message[MAX_STRING_LEN];

    while( (read_size = recv(read_sock, remote_message, MAX_STRING_LEN, 0)) > 0 )
    {
        printf(remote_message);
        fflush(stdout);
    }

    free(socket_read_desc);
    connection_active = 0;
    return 0;
}

void *connection_handler_write(void *socket_write_desc)
{
    int write_sock = *(int*)socket_write_desc;
    char local_message[MAX_STRING_LEN];

    while( connection_active != 0 )
    {
        scanf ("%[^\n]%*c", local_message);
        write(write_sock, local_message, strlen(local_message));
        memset(&local_message, 0, sizeof(local_message));
        fflush(stdin);
    }

    free(socket_write_desc);
    return 0;
}

These two functions are invoked in the main as threads with pthread_create after a new socket connection is succesfully created (so, after a successful accept). They obviously operate on the same socket.

My questions are:

1) Is this a software problem or a socket problem?

2) Which trick should I have followed, in addition to memset and fflush?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire