public override void Send(IPEndPoint endPoint, byte[] buffer, int offset, int length, bool putBufferToPool) { ValidateLength(length); try { // Some implementations throw exception if sendto is called on a connected SOCK_DGRAM socket. if (!_connectedMode) { SysSock.SendTo(buffer, offset, length, SocketFlags.None, endPoint); } else { SysSock.Send(buffer, offset, length, SocketFlags.None); } } catch (SocketException se) { // Ignore harmless errors if (!HarmlessErrors.Contains(se.SocketErrorCode)) { _logger.Exception(se); throw; } } finally { if (putBufferToPool) { _buffersPool.Put(buffer); } } }
private void SendLoop() { while (!_closing) { var packet = _sendQueue.Take(); try { if (!_connectedMode) { // This is not working for iOS/MacOS after connect call SysSock.SendTo(packet.Buffer, packet.Offset, packet.Length, SocketFlags.None, packet.EndPoint); } else { SysSock.Send(packet.Buffer, packet.Offset, packet.Length, SocketFlags.None); } } catch (SocketException se) { // Ignore harmless errors if (!HarmlessErrors.Contains(se.SocketErrorCode)) { _excQueue.Add(se); break; } } finally { if (packet.PutBufferToPool) { _buffersPool.Put(packet.Buffer); } } } }
private void ReceiveLoop() { while (!_closing) { var buffer = _buffersPool.Get(MTUSafe); var bufferInUse = false; EndPoint remoteEP = _receiveEndPoint; try { var bytesReceived = SysSock.ReceiveFrom(buffer, MTUSafe, SocketFlags.None, ref remoteEP); //ntrf: On windows we will get EMSGSIZE error if message was truncated, but Mono on Unix will fill up the // whole buffer silently. We detect this case by allowing buffer to be slightly larger, than our typical // packet, and dropping any packet, that did fill the whole thing. if (bytesReceived > 0 && bytesReceived <= MTU) { var packet = new ReceivedPacket(); packet.Buffer = buffer; packet.Offset = 0; packet.Length = bytesReceived; packet.EndPoint = (IPEndPoint)remoteEP; bufferInUse = true; _recvQueue.Add(packet); if (_recvQueue.Count > RecvQueueLimit) { // Trash oldest if (_recvQueue.TryTake(out packet)) { _buffersPool.Put(packet.Buffer); } } } else { // If blocking call isn't actually blocking, sleep for a while Thread.Sleep(10); } } catch (SocketException se) { // Ignore harmless errors if (!HarmlessErrors.Contains(se.SocketErrorCode)) { _excQueue.Add(se); break; } } if (!bufferInUse) { _buffersPool.Put(buffer); } } }
public override void Send(IPEndPoint endPoint, byte[] buffer, int offset, int length, bool putBufferToPool) { ValidateLength(length); try { // Make sure socket is live if (!Begin()) { return; } SysSock.SendTo(buffer, offset, length, SocketFlags.None, endPoint); } catch (SocketException sx) { var err = sx.SocketErrorCode; // Ignore harmless errors if (!HarmlessErrors.Contains(err)) { _logger.Exception(sx); End(); // Our socket might be killed by iOS // Make sure we'll create a new one on our next call if (err != SocketError.NotConnected) { throw sx; } } } finally { if (putBufferToPool) { _buffersPool.Put(buffer); } } }
public override void Send(byte[] buffer, int offset, int length, bool putBufferToPool) { try { // It uses Send instead of SendTo because SendTo seems not implemented in Unity on iOS SysSock.Send(buffer, offset, length, SocketFlags.None); } catch (SocketException se) { // Ignore harmless errors if (!HarmlessErrors.Contains(se.SocketErrorCode)) { _logger.Exception(se); throw; } } finally { if (putBufferToPool) { _buffersPool.Put(buffer); } } }
public override bool Receive(ref ReceivedPacket packet) { try { if (SysSock.Available == 0) { return(false); } } catch (SocketException se) { // Ignore harmless errors if (!HarmlessErrors.Contains(se.SocketErrorCode)) { _logger.Exception(se); throw; } } var buffer = _buffersPool.Get(MTUSafe); var bufferInUse = false; EndPoint remoteEP = _remoteEndPoint; try { int bytesReceived = 0; if (_connectedMode) { bytesReceived = SysSock.Receive(buffer, MTUSafe, SocketFlags.None); } else { bytesReceived = SysSock.ReceiveFrom(buffer, MTUSafe, SocketFlags.None, ref remoteEP); } //ntrf: On windows we will get EMSGSIZE error if message was truncated, but Mono on Unix will fill up the // whole buffer silently. We detect this case by allowing buffer to be slightly larger, than our typical // packet, and dropping any packet, that did fill the whole thing. if (bytesReceived > 0 && bytesReceived <= MTU) { packet.Buffer = buffer; bufferInUse = true; packet.Offset = 0; packet.Length = bytesReceived; packet.EndPoint = (IPEndPoint)remoteEP; return(true); } } catch (SocketException se) { // Ignore harmless errors if (!HarmlessErrors.Contains(se.SocketErrorCode)) { _logger.Exception(se); throw; } } finally { // We don't return buffer here if it is to be processed by client if (!bufferInUse) { _buffersPool.Put(buffer); } } return(false); }
public override bool Receive(ref ReceivedPacket packet) { byte[] buffer = null; var bufferInUse = false; try { if (!Begin()) { return(false); } if (!SysSock.Poll(0, SelectMode.SelectRead)) { return(false); } buffer = _buffersPool.Get(MTUSafe); EndPoint remoteEP = _receiveEndPoint; var bytesReceived = SysSock.ReceiveFrom(buffer, MTUSafe, SocketFlags.None, ref remoteEP); //ntrf: On windows we will get EMSGSIZE error if message was truncated, but Mono on Unix will fill up the // whole buffer silently. We detect this case by allowing buffer to be slightly larger, than our typical // packet, and dropping any packet, that did fill the whole thing. if (bytesReceived > 0 && bytesReceived <= MTU) { packet.Buffer = buffer; bufferInUse = true; packet.Offset = 0; packet.Length = bytesReceived; packet.EndPoint = (IPEndPoint)remoteEP; return(true); } } catch (SocketException sx) { var err = sx.SocketErrorCode; // Ignore harmless errors // On Windows machines we might have a case of ICMP Port Unreachable being delivered, // which causes ECONNRESET on next receive call if (!HarmlessErrors.Contains(err)) { End(); // Our socket might be killed by iOS. Recreate the socket. if (err != SocketError.NotConnected) { _logger.Exception(sx); throw; } } } finally { // We don't return buffer here if it is to be processed by client if (buffer != null && !bufferInUse) { _buffersPool.Put(buffer); } } return(false); }