ReturnCode Send(SocketSession session, byte[] sendData, bool doNotEncrypt = false) { if (!doNotEncrypt) { switch (this.encryptLevel) { case 1: sendData = Crypto.SimpleXorEncrypt(sendData, session.encryptionKey); break; case 2: sendData = Crypto.AESEncrypt(sendData, session.encryptionKey); break; } } var socket = session.socket; if (null == socket) { return(ReturnCode.ERROR_INVALID_SESSIONID); } else if (false == socket.Connected) { return(ReturnCode.ERROR_SESSION_CLOSED); } if (0 == Interlocked.CompareExchange(ref session.isSendAsyncCalled, 1, 0)) { return(_Send(session, socket, sendData)); } else { session.sendQueue.Enqueue(sendData); VerifyMissingSend(session); } return(ReturnCode.SUCCESS); }
void VerifyMissingSend(SocketSession session) { if ((0 == session.isSendAsyncCalled) && (session.sendQueue.Count > 0)) { byte[] emptyData = new byte[0]; Send(session, emptyData, true); } }
byte[] AESDecrypt(SocketSession session, byte[] data) { try { return(Crypto.AESDecrypt(data, session.encryptionKey)); } catch { return(null); } }
byte[] SimpleXorEncrypt(SocketSession session, byte[] data) { try { return(Crypto.SimpleXorEncrypt(data, session.encryptionKey)); } catch { return(null); } }
bool AssignEncyptionKey(SocketSession session, byte[] data) { try { session.encryptionKey = Crypto.RSADecrypt(Encoding.UTF8.GetString(data), this.privateKey); return(true); } catch { return(false); } }
void OnSendAsyncCompleted(SocketSession session, Socket socket, SocketAsyncEventArgs args) { var sid = session.id; if ((args.SocketError != SocketError.Success) || (0 == args.BytesTransferred)) { this.socketResourceManager.CloseSocket(socket); var list = args.BufferList as List <ArraySegment <byte> >; this.socketResourceManager.FreeArraySegmentList(list); this.socketResourceManager.FreeSocketAsyncEventArgs(args); return; } byte[] qitem; if (session.sendQueue.TryPeek(out qitem)) { var nlist = args.BufferList as List <ArraySegment <byte> >; nlist.Clear(); while (session.sendQueue.TryDequeue(out qitem)) { nlist.Add(new ArraySegment <byte>(BitConverter.GetBytes(qitem.Length))); nlist.Add(new ArraySegment <byte>(qitem)); } args.BufferList = nlist; bool asyncResult = true; try { session.IncPendingCount(this.utcNow); asyncResult = socket.SendAsync(args); } catch { session.DecPendingCount(this.utcNow); this.socketResourceManager.CloseSocket(socket); var list = args.BufferList as List <ArraySegment <byte> >; this.socketResourceManager.FreeArraySegmentList(list); this.socketResourceManager.FreeSocketAsyncEventArgs(args); return; } if (false == asyncResult) { OnSocketIOCompleted(session.socket, args); } } else { Interlocked.CompareExchange(ref session.isSendAsyncCalled, 0, 1); this.socketResourceManager.FreeSocketAsyncEventArgs(args); VerifyMissingSend(session); } }
void OnConnectAsyncCompleted(SocketSession session, Socket socket, SocketAsyncEventArgs args) { var sid = session.id; if (args.SocketError != SocketError.Success) { this.socketResourceManager.CloseSocket(socket); this.socketResourceManager.FreeSocketAsyncEventArgs(args); this.userCallback(CallbackEventType.CONNECT_FAIL, session, args.SocketError); DisposeSocketSession(session); return; } if (this.encryptLevel > 0) { // wait for public key receive } else { this.userCallback(CallbackEventType.CONNECT_SUCCESS, session, null); session.isUserCallbackHappen = true; } if (socket.Connected) { bool asyncResult = true; try { session.IncPendingCount(this.utcNow); args.SetBuffer(session.receiveBuffer, 0, session.receiveBuffer.Length); asyncResult = socket.ReceiveAsync(args); } catch { session.DecPendingCount(this.utcNow); this.socketResourceManager.CloseSocket(socket); this.socketResourceManager.FreeSocketAsyncEventArgs(args); return; } if (false == asyncResult) { OnSocketIOCompleted(socket, args); } } }
public SocketSession AllocSocketSession(Socket socket, SessionType sessionType, int receiveBufferSize = 8192) { SocketSession session = null; if (false == this.socketSessionPool.TryDequeue(out session)) { session = new SocketSession(socket, receiveBufferSize); } else { session.Clear(); session.socket = socket; } session.sessionType = sessionType; session.id = Interlocked.Increment(ref this.socketSessionID); return(session); }
void OnReceiveAsyncCompleted(SocketSession session, Socket socket, SocketAsyncEventArgs args) { var sid = session.id; if ((args.SocketError != SocketError.Success) || (0 == args.BytesTransferred)) { this.socketResourceManager.CloseSocket(socket); this.socketResourceManager.FreeSocketAsyncEventArgs(args); return; } session.IncPendingCount(this.utcNow); // to prevent disconnect while receive data processing var ret = ProcessReceivedData(session, socket, args); session.DecPendingCount(this.utcNow); if (false == ret) { this.socketResourceManager.CloseSocket(socket); this.socketResourceManager.FreeSocketAsyncEventArgs(args); return; } bool asyncResult = true; try { session.IncPendingCount(this.utcNow); asyncResult = socket.ReceiveAsync(args); } catch { session.DecPendingCount(this.utcNow); this.socketResourceManager.CloseSocket(socket); this.socketResourceManager.FreeSocketAsyncEventArgs(args); return; } if (false == asyncResult) { OnSocketIOCompleted(socket, args); } }
void OnSocketIOCompleted(object sender, SocketAsyncEventArgs args) { var socket = sender as Socket; SocketSession session = null; if (args.UserToken != null) { session = args.UserToken as SocketSession; session.DecPendingCount(this.utcNow); } else if (args.LastOperation != SocketAsyncOperation.Accept) { var list = args.BufferList as List <ArraySegment <byte> >; if (null != list) { this.socketResourceManager.FreeArraySegmentList(list); } this.socketResourceManager.FreeSocketAsyncEventArgs(args); return; } switch (args.LastOperation) { case SocketAsyncOperation.Accept: OnAcceptAsyncCompleted(socket, args); break; case SocketAsyncOperation.Connect: OnConnectAsyncCompleted(session, socket, args); break; case SocketAsyncOperation.Send: OnSendAsyncCompleted(session, socket, args); break; case SocketAsyncOperation.Receive: OnReceiveAsyncCompleted(session, socket, args); break; } }
ReturnCode _Send(SocketSession session, Socket socket, byte[] sendData) { var sid = session.id; var args = this.socketResourceManager.AllocSocketAsyncEventArgs(OnSocketIOCompleted); args.UserToken = session; var list = this.socketResourceManager.AllocArraySegmentList(); list.Add(new ArraySegment <byte>(BitConverter.GetBytes(sendData.Length))); list.Add(new ArraySegment <byte>(sendData)); args.BufferList = list; bool asyncResult = true; try { session.IncPendingCount(this.utcNow); asyncResult = socket.SendAsync(args); } catch { session.DecPendingCount(this.utcNow); this.socketResourceManager.CloseSocket(socket); this.socketResourceManager.FreeSocketAsyncEventArgs(args); this.socketResourceManager.FreeArraySegmentList(list); return(ReturnCode.ERROR_SESSION_CLOSED); } if (false == asyncResult) { OnSocketIOCompleted(socket, args); } return(ReturnCode.SUCCESS); }
void DisposeSocketSession(SocketSession session) { RemoveFromSocketSessionDic(session); this.socketResourceManager.FreeSocketSession(session); }
bool ProcessReceivedData(SocketSession session, Socket socket, SocketAsyncEventArgs args) { var dataSize = session.receiveBufferStoredDataSize + args.BytesTransferred; var readPos = 0; var sid = session.id; long readCount = long.MaxValue; if (session.readCount < 10) { readCount = Interlocked.Increment(ref session.readCount); } while (dataSize >= 4) { if (!socket.Connected) { return(false); } var packetSize = BitConverter.ToInt32(session.receiveBuffer, readPos); if (packetSize < 0) { // wrong packet size Console.WriteLine("wrong packet size!!!"); return(false); } dataSize -= 4; readPos += 4; if (dataSize >= packetSize) { if (packetSize > 0) { var seg = new ArraySegment <byte>(session.receiveBuffer, readPos, packetSize); if (this.encryptLevel > 0) { switch (session.sessionType) { case SessionType.ACCEPTED_SESSION: switch (readCount) { case 1: // peer encryption key received. decrypt & store if (!AssignEncyptionKey(session, seg.ToArray <byte>())) { return(false); } Send(session, Encoding.UTF8.GetBytes(this.encryptionKeyExchangeSuccess), true); this.userCallback(CallbackEventType.ACCEPT_SUCCESS, session.userTokenNum, sid); session.isUserCallbackHappen = true; break; default: // decrypt with session.encrytionKey and callback switch (this.encryptLevel) { case 1: var sxe = SimpleXorEncrypt(session, seg.ToArray <byte>()); if (sxe == null) { return(false); } this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, sxe); break; case 2: var aee = AESDecrypt(session, seg.ToArray <byte>()); if (aee == null) { return(false); } this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, aee); break; } break; } break; case SessionType.CONNECTED_SESSION: switch (readCount) { case 1: // public key received. send my encryption key session.encryptionKey = Crypto.CreateRandomString32(0); string ecdata = string.Empty; try { ecdata = Crypto.RSAEncrypt(session.encryptionKey, Encoding.UTF8.GetString(seg.ToArray <byte>())); } catch { return(false); } Send(session, Encoding.UTF8.GetBytes(ecdata), true); break; case 2: // connection established if (!Encoding.UTF8.GetString(seg.ToArray <byte>()).Equals(this.encryptionKeyExchangeSuccess)) { return(false); } this.userCallback(CallbackEventType.CONNECT_SUCCESS, session, null); session.isUserCallbackHappen = true; break; default: // decrypt with session.encrytionKey and callback switch (this.encryptLevel) { case 1: var sxe = SimpleXorEncrypt(session, seg.ToArray <byte>()); if (sxe == null) { return(false); } this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, sxe); break; case 2: var aee = AESDecrypt(session, seg.ToArray <byte>()); if (aee == null) { return(false); } this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, aee); break; } break; } break; } } else { this.userCallback(CallbackEventType.SESSION_RECEIVE_DATA, session, seg.ToArray <byte>()); } } dataSize -= packetSize; readPos += packetSize; } else { dataSize += 4; readPos -= 4; break; } } session.receiveBufferStoredDataSize = dataSize; if (dataSize > 0) { Buffer.BlockCopy(session.receiveBuffer, readPos, session.receiveBuffer, 0, dataSize); args.SetBuffer(session.receiveBuffer, dataSize, session.receiveBuffer.Length - dataSize); } else { args.SetBuffer(session.receiveBuffer, 0, session.receiveBuffer.Length); } return(true); }
void RemoveFromSocketSessionDic(SocketSession session) { SocketSession ss; this.socketSessionIdDic.TryRemove(session.id, out ss); }
void AddToSocketSessionDic(SocketSession session) { this.socketSessionIdDic.TryAdd(session.id, session); }
public ReturnCode CloseSession(SocketSession session) { this.socketResourceManager.CloseSocket(session.socket); return(ReturnCode.SUCCESS); }
public void FreeSocketSession(SocketSession session) { session.id = 0; this.socketSessionPool.Enqueue(session); }
public ReturnCode Send(SocketSession session, byte[] sendData) { return(Send(session, sendData, doNotEncrypt: false)); }