hololens socket can't receive full packet

eXploduseXplodus
edited December 2017 in Questions And Answers

A simple summary:

boost asio server, send a video frame 1280x720x3 with simple compression
packet size is 186476, not really to much
Nothing to complicated. Anyway, no matter if i test it in the hololens emulator or on the physical device it doesn't make a difference

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

but the hololens can't receive the full packet, i try it also with the .net streamsockets, same result. it tried a few times and then recv blocks in the while loop and doesn't receive anymore.

I also do some tests if there is coming a -1 on recv, but it isn't. I add some logging to see more informations. At the first call it recv 16060. In the second call 1460. Then it hangs and doesn't recv anymore. If i break or kill the Test i see in the boost asio server that it has send 131072.

anyone, any idea? is it an uwp app problem, that i can't receive 'bigger' packets, or get it killed because it takes too long?

Answers

  • This is my network code, which works for 500k data transfers (and more).

    Header

        Windows::Networking::Sockets::StreamSocket^       m_clientSocket = ref new Windows::Networking::Sockets::StreamSocket();
        Windows::Storage::Streams::DataWriter^            m_sendStream = nullptr;
        Windows::Storage::Streams::DataReader^            m_readStream = nullptr;
    

    Body

      Client::Client()
      {
        m_clientSocket->Control->KeepAlive = true;
        m_clientSocket->Control->NoDelay = false; // true => accumulate data until enough has been queued to occupy a full TCP/IP packet
        m_sendStream = ref new DataWriter(m_clientSocket->OutputStream);
        m_readStream = ref new DataReader(m_clientSocket->InputStream);
      }
    
      IAsyncOperation<bool>^ IGTClient::ConnectAsync(double timeoutSec)
      {
        if (m_connected)
        {
          return create_async([]() {return true;});
        }
    
        // Connect to the server (by default, the listener we created in the previous step).
        return create_async([this, timeoutSec]() -> task<bool>
        {
          return create_task(m_clientSocket->ConnectAsync(m_hostName, m_serverPort)).then([this](task<void> previousTask)
          {
            try
            {
              // Try getting all exceptions from the continuation chain above this point.
              previousTask.get();
              m_connected = true;
            }
     ....
    
      int32 Client::SocketReceive(void* dest, int size)
      {
        std::lock_guard<std::mutex> guard(m_socketMutex);
        auto loadTask = create_task(m_readStream->LoadAsync(size));
        int bytesLoaded(-1);
        try
        {
          bytesLoaded = loadTask.get();
          if (bytesLoaded != size)
          {
            return bytesLoaded;
          }
    
          auto buffer = m_readStream->ReadBuffer(size);
          if (dest != nullptr)
          {
            auto header = GetDataFromIBuffer<byte>(buffer);
            memcpy(dest, header, size);
          }
        }
        catch (...)
        {
          return -1;
        }
    
        return bytesLoaded;
      }
    
Sign In or Register to comment.