2

I have this scenario. I'm trying to use socket in C to send and receive data. Client sends some string, server manipulates it, sends it back to the client. Everything is fine but one small issue is: The client receives only the first line from server, displays it and then halts till the connection is closed by server after a time out. Although the bytes sent by server = the bytes received by client. As soon as the connection is closed, the rest of the string is displayed by the client.

I would like to know your thoughts and possible issues. Please let me know if you ahve any questions.

Protocol used: TCP

Here is the code for the server:

for (;;)
    {
            n=recv(s, buf, RBUFLEN-1, 0);
        if (n < 0)
        {
            printf("Read error\n");
            closesocket(s);
            printf("Socket %d closed\n", s);
            break;
        }
        else if (n==0)
        {
            printf("Connection closed by party on socket %d\n",s);
            closesocket(s);
            break;
        }
        else
        {
            printf("Received line from socket %03d : \n",s);
            printf("N bytes received: %d \n",n);
                     // DoSomeOperationsOnTheData() 
                 if(send(s, buffer, n, 0) != n)
            printf("Write error while replying\n");
        else
        {
            printf("Reply sent: %d bytes\n",n);
        }
    }

Code for client:

do
   {
    memset(buffer,0x0,BUFFER_SIZE);    //  init line
        rc = read(sd, buffer, BUFFER_SIZE);
        printf("\nReceived bytes: %d", rc);
        if( rc > 0)
        {
            printf("%s",buffer);
            size +=rc;
        }
    }while(rc>0);

    printf("\n   Total recieved response bytes: %d\n",size);

    close(sd);
fresh learner
  • 467
  • 4
  • 22
  • 1
    I have a question. What does your code look like? Also, look at [http://stackoverflow.com/questions/2348536/c-sockets-client-server-lag/2348543#2348543] (http://stackoverflow.com/questions/2348536/c-sockets-client-server-lag/2348543#2348543) – thuovila Aug 31 '13 at 18:34
  • you can see the code now – fresh learner Aug 31 '13 at 19:01

2 Answers2

1

This

do
{
  memset(buffer, 0, BUFFER_SIZE);    //  init line
  rc = read(sd, buffer, BUFFER_SIZE);
  printf("\nReceived bytes: %d", rc);
  if( rc > 0)
  {
    printf("%s",buffer);
    size +=rc;
  }
}while(rc>0);

should be:

memset(buffer,0x0,BUFFER_SIZE);    //  init line
size_t size = 0;
size_t toread = BUFFER_SIZE;
do
{
  ssize_t rc = read(sd, buffer+size, toread);

  if (rc > 0)
  {
    printf("\nReceived bytes:%zd", rc);
    printf("%s", buffer);
    size += rc;
    toread -= rc;
  }
  else if (rc == 0)
  {
    printf("The server hung up.\");
    break;
  }
  else
  {
    perror("read() failed");
    break;
  }
} while (toread);

if (toread < BUFFERSIZE)
{
  printf("Warning: Read less bytes (%zu) then expected (%d).\n", toread, BUFFERSIZE);
}
alk
  • 69,737
  • 10
  • 105
  • 255
0

try flush data after sent. it needs if you use socket with fdopen

FILE *fdsock = fdopen(sock, "a+");
...
fwrite(fdsock, 1, 1 "A");
fflush(fdsock);
...
fclose(fdsock);

and to finish socket, close with shutdown(sock, SD_SEND);

UPDATE

Take memset out of loop

Dmitry
  • 877
  • 1
  • 16
  • 30
  • 1
    To the best of my knowledge, that does not work. See e.g. [http://stackoverflow.com/questions/855544/is-there-a-way-to-flush-a-posix-socket] (http://stackoverflow.com/questions/855544/is-there-a-way-to-flush-a-posix-socket) – thuovila Aug 31 '13 at 18:40
  • Ouch ...! This shoudn't even compile, but at least yell out a warning. – alk Aug 31 '13 at 18:40
  • Sockets are written to using unbuffered I/O, so no flushing is ever needed. Once `write()` returned the data is off and away in the ip stack. – alk Aug 31 '13 at 18:41
  • sorry, forgot write. Used if socket will open fdopen(sock, "w+"); – Dmitry Aug 31 '13 at 18:44
  • Guys, this did work in a sense that client received all the data at once but it disturbed some other portions. So i'm not going with this solution. – fresh learner Aug 31 '13 at 18:49
  • i think its normal practic for some cases. See http://stackoverflow.com/questions/13443122/detect-eof-on-a-fgets-while-loop – Dmitry Aug 31 '13 at 18:58
  • Assuming `int sock`: you **cannot** pass an `int` where a `FILE*` is expected. – alk Aug 31 '13 at 19:01
  • However this approach does not answer the question. – alk Aug 31 '13 at 19:33
  • yes, can't found answer without authors code. I just assumed. I explained my idea here and maybe someone else found solution. – Dmitry Sep 01 '13 at 12:00