Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从unix本地套接字接收和缓冲区大小_C++_Sockets_Unix - Fatal编程技术网

C++ 从unix本地套接字接收和缓冲区大小

C++ 从unix本地套接字接收和缓冲区大小,c++,sockets,unix,C++,Sockets,Unix,我在unix本地套接字方面遇到问题。在读取比我的临时缓冲区长的消息时,请求花费的时间太长(可能是无限期的) 在一些测试后添加: 冻结在::recv时仍然存在问题。当我将(1023*8)字节或更少的字节发送到UNIX套接字时(一切正常,但当发送的字节数超过(1023*9)时),我会在recv命令上冻结。 也许它的FreeBSD默认UNIX套接字限制或C++默认套接字设置?谁知道呢? 我做了一些额外的测试,我100%确信在执行::recv命令时,当试图读取长度为>=(1023*9)字节的消息时,它

我在unix本地套接字方面遇到问题。在读取比我的临时缓冲区长的消息时,请求花费的时间太长(可能是无限期的)

在一些测试后添加: 冻结在::recv时仍然存在问题。当我将(1023*8)字节或更少的字节发送到UNIX套接字时(一切正常,但当发送的字节数超过(1023*9)时),我会在recv命令上冻结。 <强>也许它的FreeBSD默认UNIX套接字限制或C++默认套接字设置?谁知道呢?



我做了一些额外的测试,我100%确信在执行::recv命令时,当试图读取长度为>=(1023*9)字节的消息时,它在最后9次写入时“冻结”。(第一,一切进展顺利。) 我在做什么: 其思想是使用

::recv (current_socket, buf, 1024, 0);
并选中
buf
以查看特殊符号。如果未找到:

  • 将缓冲区的内容合并到
    stringxxx+=buf
  • 零温度
  • 继续::recv循环
  • 如何解决while循环中请求耗时过长的问题?

    有没有更好的方法清除缓冲区?目前,它是:

     char buf [1025];
     bzero(buf, 1025);
    
    <>但是我知道B0在新的C++标准中是不成立的。 编辑: *“为什么需要清理缓冲区*

    我在这个问题的评论中看到问题。如果在下一次(最后一次)读取缓冲区时没有缓冲区清理,它将包含消息第一部分的“尾部”

    例如:

     // message at the socket is "AAAAAACDE"
     char buf [6];
     ::recv (current_socket, buf, 6, 0); // read 6 symbols, buf = "AAAAAA"
     // no cleanup, read the last part of the message with recv
     ::recv (current_socket, buf, 6, 0); 
     // read 6 symbols, but buffer contain only 3 not readed before symbols, therefore
     // buf now contain "CDEAAA" (not correct, we waiting for CDE only)
    

    您可以使用

    memset(buf, 0, 1025);
    

    您可以使用

    memset(buf, 0, 1025);
    

    这是两个独立的问题。很长时间可能是由于代码中的错误导致的无限循环,与清除缓冲区的方式无关。事实上,您不需要清除缓冲区;receive返回读取的字节数,因此您可以在缓冲区中扫描特殊的_符号,直到该点


    如果您粘贴代码,我可能会有所帮助。更多。

    这是两个独立的问题。由于代码中存在错误,很长时间可能是无限循环,与清除缓冲区的方式无关。事实上,您不需要清除缓冲区;receive返回读取的字节数,因此您可以扫描缓冲区r特殊的_符号


    <> >如果你粘贴代码,我可以帮助。更多。

    < p>只是澄清:<代码> B0/<代码>在C++ 11中不被禁止。相反,它从来不是任何C或C++标准的一部分。C开始时用<代码> MyStuts< /C> 20 + +年。对于C++,你可以考虑使用<代码> STD::FILIN n < /C>(或者只使用
    std::vector
    ,它可以自动归零填充)我不知道在这种情况下,有没有理由在这个例子中填充缓冲区。< / P> < P>只是澄清:<代码> B0/<代码>在C++ 11中不被禁止。相反,它从来不是任何C或C++标准的一部分。C开始时用<代码> MyStuts< /C> 20 + +年。对于C++,您可以考虑使用<代码> STD::FILIN n < /C>(或者只是使用可以自动零填充的
    std::vector
    )然后,我也不确定在这种情况下有什么好的理由零填充缓冲区。

    当您的
    recv()
    进入无限循环时,这可能意味着它在迭代中没有取得任何进展(也就是说,您总是立即得到一个零大小的短读取,因此您的循环永远不会退出,因为您没有得到任何数据)。对于流套接字,零大小的
    recv()
    表示远程端已断开连接(这类似于当输入位于EOF时从文件读取
    read()
    也会得到零字节),或者至少它已经关闭了发送通道(特别是TCP)

    检查您的PHP脚本是否实际发送了您声称它发送的数据量

    要添加在循环中正确使用recv()的小(非感官)示例,请执行以下操作:

    char buf[1024];
    std::string data;
    while( data.size() < 10000 ) { // what you wish to receive
        ::ssize_t rcvd = ::recv(fd, buf, sizeof(buf), 0);
        if( rcvd < 0 ) {
            std::cout << "Failed to receive\n";  // Receive failed - something broke, see errno.
            std::abort();
        } else if( !rcvd ) {
            break; // No data to receive, remote end closed connection, so quit.
        } else {
            data.append(buf, rcvd); // Received into buffer, attach to data buffer.
        }
    }
    
    if( data.size() < 10000 ) {
        std::cout << "Short receive, sender broken\n";
        std::abort();
    }
    
    // Do something with the buffer data.
    
    charbuf[1024];
    std::字符串数据;
    而(data.size()<10000){//您希望接收的内容
    ::ssize_t rcvd=::recv(fd,buf,sizeof(buf),0);
    if(rcvd<0){
    std::cout当你的
    recv()
    进入一个无限循环时,这可能意味着它在迭代中没有任何进展(即,你总是立即得到一个零大小的短读取,因此你的循环永远不会退出,因为你没有得到任何数据)
    大小为零意味着远程端已断开连接(这类似于当输入位于EOF时从文件中读取()
    也会得到零字节),或者至少它已关闭发送通道(这是专门针对TCP的)

    检查您的PHP脚本是否实际发送了您声称它发送的数据量

    要添加在循环中正确使用recv()的小(非感官)示例,请执行以下操作:

    char buf[1024];
    std::string data;
    while( data.size() < 10000 ) { // what you wish to receive
        ::ssize_t rcvd = ::recv(fd, buf, sizeof(buf), 0);
        if( rcvd < 0 ) {
            std::cout << "Failed to receive\n";  // Receive failed - something broke, see errno.
            std::abort();
        } else if( !rcvd ) {
            break; // No data to receive, remote end closed connection, so quit.
        } else {
            data.append(buf, rcvd); // Received into buffer, attach to data buffer.
        }
    }
    
    if( data.size() < 10000 ) {
        std::cout << "Short receive, sender broken\n";
        std::abort();
    }
    
    // Do something with the buffer data.
    
    charbuf[1024];
    std::字符串数据;
    而(data.size()<10000){//您希望接收的内容
    ::ssize_t rcvd=::recv(fd,buf,sizeof(buf),0);
    if(rcvd<0){
    
    std::cout为什么必须清除缓冲区?你可以从
    recv()
    的返回值中知道复制了多少字节。我不确定你为什么需要一个特殊字符才能知道你已经超过了缓冲区长度。套接字是在非阻塞模式下打开的吗?请参阅
    fcntl()
    的手册页。Martin,在“编辑”处回答“第一条消息的一部分..chrisaycock,因为缓冲区大小可以小于消息的大小。(在我的示例中,它的读取不超过缓冲区大小,受::recv处的第三个参数限制)为什么必须清除缓冲区?您可以从
    recv()中了解< /Cord>的返回值:复制了多少字节。我不知道为什么你需要一个特殊的字符来知道你已经超过了你的缓冲区长度。套接字是在非阻塞模式下打开的吗?参见“man代码页>代码> fCNTL())/>代码。马丁,在“编辑”PAR处回答。