【问题标题】:Two consecutive socket reads, second read not working两次连续的套接字读取,第二次读取不起作用
【发布时间】:2013-02-23 23:53:25
【问题描述】:

下面是我的服务器代码和客户端代码的代码段。我的客户端向服务器发送一个成功接收的整数,然后我向服务器发送一个长度为 str_len 的字符串。服务器中的第二次读取不起作用,它正在阻塞并且不读取任何内容。当我退出客户端时,服务器会打印出它没有读取任何内容。怎么了?

            //Server code

            bzero(buffer,256);
            n = read(newsockfd,buffer,255);
            if (n < 0) error("ERROR reading from socket");
            unsigned int *length = new unsigned int;
            memcpy(length, buffer, sizeof(int));
            cout << "Length : " << *length << endl;
            int len = *length + 1;
            char buffIn[len+1];
            bzero(buffIn,len);
            //ok msg?
            n = read(newsockfd,buffIn,len);
            if (n < 0) error("ERROR reading from socket");
            cout << "value of n" << n << endl;
            printf("Received : %s\n", buffIn);


            //client method

            void send(string req)
            {
                //Send string len
                unsigned int str_len = req.length();
                //str_len = 3000;
                write(socketFd, &str_len, sizeof(str_len));
                //Send string
                const char *str_req = req.c_str();
                printf("%s\n",str_req);
                cout << "Str len is : " << strlen(str_req) << endl;
                write(socketFd, str_req, strlen(str_req) + 1);
                cout << "write done " << endl;
            }

【问题讨论】:

  • 你有没有检查过第一次读取收到了多少字节?很可能这两个发送命令的数据是通过一个数据包发送和接收的,因此在第一次读取后就已经交给了应用程序。
  • 您通过从套接字读取 255 个字节来读取 str 长度,从而拉入数据的前 251 个(假设为 32 位整数)。因此,当您要求字符串的其余部分时,您要求额外的 251 个字节未发送,因此读取调用阻塞
  • 只使用"unsigned int length; n=read(newsockfd,&length, sizeof(length));"

标签: c++ c tcp


【解决方案1】:

考虑这一行:

n = read(newsockfd,buffer,255);

您永远不会随后检查n 的精确值。您检查函数是否失败,但不检查读取了多少字节。提示:在你的情况下,它不仅仅是sizeof (int)

试试这个:

n = read(newsockfd, buffer, sizeof(int));

N.b.:在其他情况下,它也可能小于sizeof(int)。你也必须处理这种情况。

【讨论】:

  • 很好的说明,读取的字节数可能小于请求的字节数
【解决方案2】:

您从套接字读取 255 个字节的 str 长度,从而拉入数据的前 251 个(假设为 32 位整数)。因此,当您要求字符串的其余部分时,您要求额外的 251 个字节未发送,因此读取调用会阻塞。

将长度读入整数

unsigned int length;
n=read(newsockfd,&length, sizeof(length));

在您当前的代码中 sn-ps 您没有删除长度

unsigned int *length = new unsigned int;

这将导致少量内存泄漏。

正如 Rob 在他的回答中所说,您应该检查读取的返回字节数,而不仅仅是检查返回的错误

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多