【问题标题】:Client prints Half Data Before Connection is Closed By Server on Socket客户端在套接字上的服务器关闭连接之前打印一半数据
【发布时间】:2013-09-04 06:41:40
【问题描述】:

我有这种情况。我正在尝试使用 C 中的套接字来发送和接收数据。客户端发送一些字符串,服务器对其进行操作,将其发送回客户端。一切都很好,但一个小问题是:客户端只接收来自服务器的第一行,显示它然后暂停,直到连接在超时后被服务器关闭。虽然服务器发送的字节数 = 客户端收到的字节数。一旦连接关闭,客户端就会显示字符串的其余部分。

我想知道您的想法和可能的问题。如果您有任何问题,请告诉我。

使用的协议:TCP

这是服务器的代码:

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

客户端代码:

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

【问题讨论】:

标签: c sockets client-server


【解决方案1】:

这个

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

应该是:

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

【讨论】:

  • 工作就像一个魅力!!!表示问题出在客户身上。我以为是服务器。 :) 谢谢你和其他所有人!
  • 我希望我能做到 +1,但我的声誉很低。 :( 抱歉。
  • @IbrahimNadir:但您仍然可以接受答案吗?
【解决方案2】:

发送后尝试刷新数据。 如果您使用带有 fdopen 的套接字,则需要它

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

要完成套接字,请使用 shutdown(sock, SD_SEND); 关闭

更新

让 memset 退出循环

【讨论】:

  • 据我所知,这是行不通的。参见例如[stackoverflow.com/questions/855544/… (stackoverflow.com/questions/855544/…)
  • 哎哟...!这甚至不应该编译,但至少要发出警告。
  • 使用无缓冲 I/O 写入套接字,因此不需要刷新。一旦write() 返回,数据就会在 ip 堆栈中关闭。
  • 抱歉,忘记写了。如果套接字将打开,则使用 fdopen(sock, "w+");
  • 伙计们,从某种意义上说,这确实有效,因为客户端一次收到了所有数据,但它扰乱了其他部分。所以我不会使用这个解决方案。
猜你喜欢
  • 2014-07-23
  • 2013-02-17
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-11
  • 1970-01-01
相关资源
最近更新 更多