【问题标题】:hololens socket can't receive full packethololens 套接字无法接收完整的数据包
【发布时间】:2018-05-18 08:40:19
【问题描述】:

简单总结:

  • boost asio 服务器,发送一个简单压缩的 720x768x3 视频帧
  • 数据包大小为 186476,不是很大

无论如何,如果我在 hololens 模拟器或物理设备上测试它,没什么复杂的

// uint32_t data_length == size of frame 'data_ptr'
enum max_length = sizeof(uint32_t);
memcpy(data_, &data_length, max_length);
auto length = boost::asio::write(*socket_, boost::asio::buffer(data_, max_length), e);
length = boost::asio::write(*socket_, boost::asio::buffer(data_ptr, data_length), e);

// receive
char data_[max_length] = { 0 };

fd_set readSet;
FD_ZERO(&readSet);
FD_SET(_socket, &readSet);
timeval timeout;
timeout.tv_sec = 0;  // Zero timeout (poll)
timeout.tv_usec = 0;

auto result = select(_socket, &readSet, nullptr, nullptr, &timeout);
if (result == 0)
    continue;

result = recv(_socket, data_, max_length, 0);
if (result == SOCKET_ERROR) {
    closesocket(_socket);
    _socket = INVALID_SOCKET;
    break;
}

uint32_t msg_size(0);
memcpy(&msg_size, data_, max_length);

std::vector<char> vec(msg_size);
result = recv(_socket, &vec[0], msg_size, 0);

while (result < msg_size) {
    result += recv(_socket, &vec[result], msg_size - result, 0);
}

但是 hololens 无法接收完整的数据包,我也尝试使用 .net 流套接字,结果相同。它尝试了几次,然后在while循环中recv块并且不再接收。

任何人,有什么想法吗?是 uwp 应用程序问题,我无法接收“更大”的数据包,还是因为耗时太长而将其杀死?

【问题讨论】:

    标签: c++ sockets uwp hololens


    【解决方案1】:

    你有两个主要问题:

    首先,您需要检查recv 的返回值是否有错误。如果返回 0 或 -1,则需要处理。

    其次,您忽略了第一次调用recv 时收到的所有数据。当 result 减去长度占用的字节数时,您将 msg_size 设置为零。

    我建议编写一个函数来准确读取指定的字节数,检查错误。首先调用它以接收四个字节并检查它是否返回错误。然后调用它来接收你收到的长度数据所指示的字节数。

    较小的问题包括:

    如果第一个recv 只返回一个字节怎么办?

    如果您的平台存储 32 位整数的方式与模拟器发送它的方式不同怎么办?

    【讨论】:

    • 感谢您的提示,如果出现-1,我会进行一些测试,但事实并非如此。我添加了一些日志以查看更多信息。在第一次调用它 recv 16060 位。在第二次调用 1460 位。然后它挂起并且不再接收。如果我破坏或终止测试,我会在 boost asio 服务器中看到它已发送 131072 位。
    • @explodus msg_size 是什么?
    • 这是完整数据的长度,抱歉我之前评论中的位/字节错误
    • @explodus 不,我的意思是它在您报告的运行中的实际价值是多少? (因为这就是控制您的 recv 循环的原因。)
    • boost asio 服务器尝试发送 186476,如果我杀死 hololens 应用程序,我看到它已发送 131072。但 hololens 应用程序此时仅收到 17520。作为更详细的提示,套接字接收在 concurrency::agent::run 方法中运行,因此它应该在额外的“线程/任务/任何东西”中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 2017-04-09
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多