1
votes

I have written a client/server application where the server spawns multiple threads depending upon the request from client.

These threads are expected to send some data to the client(string).

The problem is, data gets overwritten on the client side. How do I tackle this issue ?

I have already read some other threads on similar issue but unable to find the exact solution.

Here is my client code to receive data.

while(1)
    {
            char buff[MAX_BUFF];
            int bytes_read = read(sd,buff,MAX_BUFF);
            if(bytes_read == 0)
            {
                    break;
            }
            else if(bytes_read > 0)
            {
                    if(buff[bytes_read-1]=='$')
                    {
                            buff[bytes_read-1]='\0';
                            cout<<buff;
                    }
                    else
                    {
                            cout<<buff;
                    }
            }
    }

Server Thread code :

void send_data(int sd,char *data)
{
    write(sd,data,strlen(data));
    cout<<data;
}

void *calcWordCount(void *arg)
{
    tdata *tmp = (tdata *)arg;
    string line = tmp->line;
    string s = tmp->arg;
    int sd = tmp->sd_c;
    int line_no = tmp->line_no;
    int startpos = 0;
    int finds = 0;
    while ((startpos = line.find(s, startpos)) != std::string::npos)
    {
            ++finds;
            startpos+=1;
            pthread_mutex_lock(&myMux);
            tcount++;
            pthread_mutex_unlock(&myMux);
    }
    pthread_mutex_lock(&mapMux);
    int t=wcount[s];
    wcount[s]=t+finds;
    pthread_mutex_unlock(&mapMux);


    char buff[MAX_BUFF];
    sprintf(buff,"%s",s.c_str());
    sprintf(buff+strlen(buff),"%s"," occured ");
    sprintf(buff+strlen(buff),"%d",finds);
    sprintf(buff+strlen(buff),"%s"," times on line ");
    sprintf(buff+strlen(buff),"%d",line_no);
    sprintf(buff+strlen(buff),"\n",strlen("\n"));
    send_data(sd,buff);
    delete (tdata*)arg;
}
2
Post the server thread code... - Ryan J
"The problem is, data gets overwritten on the client side." - That is highly unlikely. It is more likely that the "overwritting* is happen on the server side. - Stephen C
@StephenC Actually, the data from different threads seems to be sent together by TCP causing the issue. - Ajit
Why is your code that writes to the buffer and the subsequent call to send_data() not protected by a mutex? That's data you depend on to be atomic, is it not? - Ryan J
yup, but I tried by protecting that call..still no good.. - Ajit

2 Answers

3
votes
  1. On the server side make sure the shared resource (the socket, along with its associated internal buffer) is protected against the concurrent access.
  2. Define and implement an application level protocol used by the server to make it possible for the client to distinguish what the different threads sent.

As an additional note: One cannot rely on read()/write() reading/writing as much bytes as those two functions were told to read/write. It is an essential necessity to check their return value to learn how much bytes those functions actually read/wrote and loop around them until all data that was intended to be read/written had been read/written.

-1
votes

You should put some mutex to your socket.

When a thread use the socket it should block the socket.

Some mutex example.

I can't help you more without the server code. Because the problem is probably in the server.