/// <summary> /// This member is the entry point for the receive thread. This thread creates (or waits for) the connection /// to the remote counterpart, and then continually recieves complete messages into inbox until the socket /// is closed.The correct way to terminate this thread is to close the socket, which will end any waiting. /// </summary> private void ReceiveThreadFunction() { byte[] buffer = new byte[UDP_MAX_DATAGRAM_SIZE]; // working memory for receiving udp packets. this is the max size according to udp. our max size may be smaller. // make sure this block surrounds the entire function, as otherwise exceptions may disappear. try { ConnectWithRemoteEndpoint(); // ready to start sending sendthread.Start(); while (true) { /* * If you are using a connectionless Socket, Receive will read the first queued datagram from the * destination address you specify in the Connect method. If the datagram you receive is larger * than the size of the buffer parameter, buffer gets filled with the first part of the message, * the excess data is lost and a SocketException is thrown. * https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.receive?view=netframework-4.8 */ int receieved = socket.Receive(buffer); if (receieved == 0) { break; // the socket has been gracefully closed. } if (receieved < HEADERSIZE) { throw new IncompleteMessageException(); } int size = Packing.GetInt(buffer, 0); if (size != receieved - HEADERSIZE) { throw new IncompleteMessageException(); } ReferenceCountedMessage m = pool.Rent(size); Buffer.BlockCopy(buffer, HEADERSIZE, m.bytes, m.start, size); messagesreceived.Enqueue(m); } } catch (ObjectDisposedException) { Debug.Log(def.ToString() + " Receive Shutdown."); } catch (SocketException e) { switch (e.ErrorCode) { case WSAEINTR: Debug.Log(def.ToString() + " Receive Shutdown"); return; default: Debug.LogException(e); return; } } catch (Exception e) { Debug.LogException(e); } }