繁体   English   中英

从Unix本地套接字接收和缓冲区大小

[英]receive from unix local socket and buffer size

我在使用Unix本地套接字时遇到问题。 在读取长度超过我的临时缓冲区大小的消息时,请求花费的时间太长(可能无限期)。

经过一些测试后添加 ::: recv处的冻结仍然存在问题。 当我向UNIX套接字发送(1023 * 8)个字节或更少的字节时-一切正常,但是当发送大于(1023 * 9)个字节时-我在recv命令中冻结。 也许它的FreeBSD默认UNIX套接字限制或C ++默认套接字设置? 谁知道?


我进行了一些附加测试,当尝试读取长度大于等于(1023 * 9)字节的消息时,我100%确信在执行:: recv命令时,它在最后第9次“冻结”。 (第8次发送信号良好)。

我在做什么:的想法是从一个套接字读取do / while循环

::recv (current_socket, buf, 1024, 0);

并检查buf是否有特殊符号。 如果找不到:

  1. 将缓冲区的内容合并到stringxxx += buf;
  2. bzero临时buf
  3. 继续:: recv循环

如何解决while循环中的请求时间过长的问题?

有更好的方法清除缓冲区吗? 当前是:

 char buf [1025];
 bzero(buf, 1025);

但是我知道在新的c ++标准中不赞成使用bzero。

编辑: * “为什么需要清理缓冲区 *

我在有关此问题的评论中看到了问题。 如果不对下一次(最后一次)读取缓冲区进行缓冲区清除,它将包含消息第一部分的“尾部”。

例:

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

除了bzero ,您可以使用

memset(buf, 0, 1025);

这些是2个独立的问题。 时间长了可能是由于代码中的错误导致的无限循环,与清除缓冲区的方式无关。 事实上,您不必清除缓冲区; receive返回读取的字节数,因此您可以在此之前扫描缓冲区中的SPECIAL_SYMBOL。

如果您粘贴代码,也许我可以帮助您。 更多。

需要澄清的是: bzero在C ++ 11中并未被弃用。相反,它从未成为任何 C或C ++标准的一部分。 C始于20年前的memset 对于C ++,您可以考虑使用std::fill_n代替(或仅使用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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM