fresh learner
fresh learner

Reputation: 467

Client prints Half Data Before Connection is Closed By Server on Socket

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);

Upvotes: 2

Views: 246

Answers (2)

alk
alk

Reputation: 70921

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);
}

Upvotes: 1

Dmitry
Dmitry

Reputation: 867

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

Upvotes: 0

Related Questions