private void BeginSend() { Socket sock = _socket; try { sock.BeginSend(_outputBuf.ByteArray, 0, _outputBuf.Count, SocketFlags.None, ar => { _actions.Enqueue(() => { try { var sent = sock.EndSend(ar); _outputBuf.EraseAndCompact(sent, ReserveOutputBufSize); if (_outputBuf.Count > 0) { BeginSend(); } } catch (Exception e) { Close(sock, e); } }); }, null); } catch (Exception e) { Close(sock, e); } }
private void ProcessInput() { if (!_socket.Poll(0, SelectMode.SelectRead)) { return; } int received = _socket.Receive(_input, _input.Length, SocketFlags.None); if (received <= 0) { throw new Exception("Socket.Receive received = " + received); } _inputBuf.Append(_inputSecurity.Update(_recvo.WrapBytes(_input, received))); var os = _recvos.WrapOctets(_inputBuf); while (os.Remaining > 0) { int tranpos = os.Begin(); try { int type = os.UnmarshalSize(); int size = os.UnmarshalSize(); if (size > os.Remaining) { os.Rollback(tranpos); break; // not enough } _protocolStrs.Add(new ProtocolStruct(type, os.UnmarshalFixedSizeBytes(size))); //因为回调里,可能Close了Link,则os底层的_inputBuf也已经clear了。 if (ConnectState != ConnectState.Connected) { return; } } catch (MarshalException) { os.Rollback(tranpos); break; } } if (os.Position != 0) { _inputBuf.EraseAndCompact(os.Position, ReserveInputBufSize); } }
private void ProcessOutput() { if (_outputBuf.Count == 0) { return; } if (_outputBuf.Count > OutputBufferSize) { // 如果输入流大小大于定义的大小,断开连接 throw new Exception("Exceed OutputBufferSize. curr = " + _outputBuf.Count + ", max = " + OutputBufferSize); } // 清空输出流 int sendByteOffset = 0; int lastSend = 0; while (_outputBuf.Count > sendByteOffset) { //不可写,等待下次Update继续判断 if (!_socket.Poll(0, SelectMode.SelectWrite)) { break; } lastSend = _socket.Send(_outputBuf.ByteArray, sendByteOffset, _outputBuf.Count - sendByteOffset, SocketFlags.None); if (lastSend <= 0) { break; } sendByteOffset += lastSend; } if (lastSend < 0) { throw new Exception("Socket.Send return = " + lastSend); } if (sendByteOffset > 0) { _outputBuf.EraseAndCompact(sendByteOffset, ReserveOutputBufSize); } }
private void BeginReceive() { Socket sock = _socket; //closure 的问题,需要这句 try { sock.BeginReceive(_input, 0, InputSize, SocketFlags.None, ar => { _actions.Enqueue(() => { try { int received = sock.EndReceive(ar); if (received > 0) { _inputBuf.Append(_inputSecurity.Update(Octets.Wrap(_input, received))); var os = OctetsStream.Wrap(_inputBuf); while (os.Remaining > 0) { int tranpos = os.Begin(); try { int type = os.UnmarshalSize(); int size = os.UnmarshalSize(); if (size > os.Remaining) { os.Rollback(tranpos); break; // not enough } _protocols.Enqueue(new Protocol(type, os.UnmarshalFixedSizeBytes(size))); } catch (MarshalException) { os.Rollback(tranpos); break; } } if (os.Position != 0) { _inputBuf.EraseAndCompact(os.Position, ReserveInputBufSize); } BeginReceive(); } else { Close(sock, new Exception("the socket channel has reached end-of-stream")); } } catch (Exception e) { Close(sock, e); } }); }, null); } catch (Exception e) { Close(sock, e); } }