public void Send() { if (sendBuffer.Length <= 0)//没有任何数据 { return; } try { //SysSocket.BeginSend(sendBuffer.ToArray(), 0, sendBuffer.Count, SocketFlags.None, null, null); int realSendLen = sysSocket.Send(sendBuffer.Buffer, sendBuffer.Start, sendBuffer.Length, SocketFlags.None); //LastTickSend += realSendLen; if (realSendLen == sendBuffer.Length) { //if (sendBuffer.Length >= 1024 * 4) //{ // if (endPoint < sendBuffer.Length / 4) //一直达不到25%使用率,会释放掉一般空间 // { // shrinkHint++; // if (shrinkHint == 5) // { // sendBuffer = new byte[sendBuffer.Length / 4]; // shrinkHint = 0; // } // } // else // { // shrinkHint = 0; // } //} sendBuffer.Reset(); } else { sendBuffer.Pop(realSendLen); } } catch (SocketException e) { if (e.ErrorCode != 10035) //WSAEWOULDBLOCK,这个错误调试时会出现 { Log.Debug("UXSocket.SendData error connectId={0} errorCode={1} msg={2}", Id, e.ErrorCode, e.Message); } if (UserId > 0 || e.ErrorCode == 10054 || e.ErrorCode == 10053 || e.ErrorCode == 10058)//UserId > 0主要是客户端,10054是远程强制关闭的情况 { sendBuffer.Reset(); DefferedClose = true; } } catch (Exception e) { sendBuffer.Reset(); Log.Warn("UXSocket.SendData error={0}", e); DefferedClose = true; } }
public void Send() { // no data in sendBuffer // neednt to send data if (sendBuffer.Length <= 0) { return; } try { //SysSocket.BeginSend(sendBuffer.ToArray(), 0, sendBuffer.Count, SocketFlags.None, null, null); int realSendLen = sysSocket.Send(sendBuffer.Buffer, sendBuffer.Start, sendBuffer.Length, SocketFlags.None); // todo support for statistics here if (realSendLen == sendBuffer.Length) { // todo add shrink capablity to buffer sendBuffer.Reset(); } else { sendBuffer.Consume(realSendLen); } } catch (SocketException e) { // WSAEWOULDBLOCK // occurs when debug server group if (e.ErrorCode != 10035) { Log.Debug("Connector.SendData error connectId={0} errorCode={1} msg={2}", Id, e.ErrorCode, e.Message); } // todo specially, when the connector remote is frontend-client, any errors would cause DefferedClose // this can be done in gate if (e.ErrorCode == 10054 || e.ErrorCode == 10053 || e.ErrorCode == 10058) { // 10054 stands for a close of remote sendBuffer.Reset(); DefferedClose = true; } } catch (Exception e) { sendBuffer.Reset(); Log.Warn("Connector.SendData error={0}", e); DefferedClose = true; } }
// io thread schedules this entrance private void OnReceivedCallback(IAsyncResult ar) { int bytesRead = 0; try { if (sysSocket != null) { bytesRead = sysSocket.EndReceive(ar); } } catch (ObjectDisposedException e) { Log.Debug("Connector.ReceiveCallback objectDisposedException connectId={0}", Id); DefferedClose = true; return; } catch (SocketException e) { Log.Debug("Connector.ReceiveCallback connectId={0} errorCode={1} errorMessage={2}", Id, e.ErrorCode, e.Message); if (e.ErrorCode == 10054 || e.ErrorCode == 10053 || e.ErrorCode == 10058) { // todo specially, when the connector remote is frontend-client, any errors would cause DefferedClose // this can be done in gate DefferedClose = true; } return; } catch (Exception) { // unknown errors Log.Error("Connector.ReceiveCallback exception connectId={0}", Id); DefferedClose = true; return; } if (bytesRead == 0) { Log.Debug("Connector.ReceiveCallback read is 0 connectId={0}", Id); // todo specially, when the connector remote is frontend-client, any errors would cause DefferedClose // this can be done in gate // remember this return, or it will go to a infinity recursion return; } receiveBuffer.Produce(bytesRead); // todo support for statistics here while (receiveBuffer.Length >= HeadLen) { // todo a strange bug occurs here ever int size = BitConverter.ToInt32(receiveBuffer.Buffer, receiveBuffer.Start); if (size < 0) { Log.Warn("Connector.ReceiveCallback size={0} id={1} buffer={2} bytesRead={3}", size, Id, receiveBuffer, bytesRead); break; } if (receiveBuffer.Length >= size + HeadLen) { byte[] destBuffer = null; destBuffer = new byte[size]; Buffer.BlockCopy(receiveBuffer.Buffer, receiveBuffer.Start + HeadLen, destBuffer, 0, size); // decode if (rc4Read != null) { rc4Read.Encrypt(destBuffer, size); } // todo add shrink capablity to buffer receiveBuffer.Reset(); try { MessageQueueEnqueue(destBuffer); } catch (Exception e) { Log.Error(e); } } else { // remained data is still uncoming // wait for next callback, // since tcp is a stream-based protocol break; } } Receive(); }