private void HandleBadAccept(SocketAsyncEventArgs acceptEventArgs) { if (acceptEventArgs == null) { return; } AcceptOpUserToken acceptOpToken = acceptEventArgs.UserToken as AcceptOpUserToken; if (acceptOpToken == null) { return; } SocketListener.Log.Write("Closing socket of accept id " + acceptOpToken.TokenId); // 소켓 Close, managed and unmanaged 자원 해제 // (내부적으로 Dispose 호출함) if (acceptEventArgs.AcceptSocket != null) { acceptEventArgs.AcceptSocket.Close(); } poolOfAcceptEventArgs.Push(acceptEventArgs); }
/// <summary> /// Accept 비동기 완료시 호출 /// </summary> private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e) { if (!ValidationCheckSocketAsyncEventArgs("AcceptEventArg_Completed", e)) { SocketListener.Log.WRN("AcceptEventArg_Completed : ValidationCheckSocketAsyncEventArgs fail."); this.HandleBadAccept(e); this.StartAccept(); return; } IPEndPoint remoteIpEndPoint = e.AcceptSocket.RemoteEndPoint as IPEndPoint; if (remoteIpEndPoint == null) { SocketListener.Log.ERR("AcceptEventArg_Completed : SocketAsyncEventArgs invalid remoteIpEndPoint."); this.HandleBadAccept(e); this.StartAccept(); return; } string strRemoteIp = remoteIpEndPoint.Address.ToString(); int nReportPort = remoteIpEndPoint.Port; AcceptOpUserToken userToken = e.UserToken as AcceptOpUserToken; userToken.RemoteIp = remoteIpEndPoint.Address.ToString(); userToken.RemotePort = remoteIpEndPoint.Port; userToken.IpEndPt = remoteIpEndPoint; SocketListener.Log.MSG(e, "AcceptEvent completed."); ProcessAccept(e); }
internal void WRN(SocketAsyncEventArgs e, params string[] messages) { string strMsg = ""; string strRemoteIp = ""; int nRemotePort = 0; int nToken = 0; DataHoldingUserToken dToken = e.UserToken as DataHoldingUserToken; if (dToken != null) { strRemoteIp = dToken.RemoteIp; nRemotePort = dToken.RemotePort; nToken = dToken.TokenId; } else { AcceptOpUserToken aToken = e.UserToken as AcceptOpUserToken; strRemoteIp = aToken.RemoteIp; nRemotePort = aToken.RemotePort; nToken = aToken.TokenId; } strMsg = string.Format("{0,-15}:{1}/{2}|{3}" , strRemoteIp , nRemotePort , nToken , string.Join("\t", messages) ); AppLog.Write(LOG_LEVEL.WRN, strMsg); }
/// <summary> /// Accept SAEA 객체 생성 /// </summary> private SocketAsyncEventArgs CreateNewSaeaForAccept(SocketAsyncEventArgsPool pool) { SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs(); acceptEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(AcceptEventArg_Completed); AcceptOpUserToken theAcceptOpToken = new AcceptOpUserToken(pool.AssignTokenId() + 10000); acceptEventArg.UserToken = theAcceptOpToken; return(acceptEventArg); }
private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs) { // 이벤트 검사 if (!ValidationCheckSocketAsyncEventArgs("ProcessAccept", acceptEventArgs)) { this.StartAccept(); this.HandleBadAccept(acceptEventArgs); return; } // 최대 접속자 수 설정 Int32 max = this.maxSimultaneousClientsThatWereConnected; Int32 numberOfConnectedSockets = Interlocked.Increment(ref this.numberOfAcceptedSockets); if (numberOfConnectedSockets > max) { Interlocked.Increment(ref this.maxSimultaneousClientsThatWereConnected); } // 다음 소켓 이벤트 대기 처리 : acceptEventArgs -> recvEventArgs, sendEventArgs StartAccept(); SocketListener.Log.MSG(acceptEventArgs, string.Format("Start accept processing !! poolOfAcceptEventArgs:{0}, poolOfRecvEventArgs:{1}, poolOfSendEventArgs:{2}" , this.poolOfAcceptEventArgs.Count , this.poolOfRecvEventArgs.Count , this.poolOfSendEventArgs.Count)); try { // Accept 된 Client 로 추가 : acceptEventArgs -> recvEventArgs, sendEventArgs if (this.poolOfRecvEventArgs.Count <= 1 || this.poolOfSendEventArgs.Count <= 1) { this.CreateNewSaeaForRecvSendOne(); } AcceptOpUserToken aToken = acceptEventArgs.UserToken as AcceptOpUserToken; SocketAsyncEventArgs recvEventArgs = null; SocketAsyncEventArgs sendEventArgs = null; while (true) { recvEventArgs = this.poolOfRecvEventArgs.Pop(); sendEventArgs = this.poolOfSendEventArgs.Pop(); if (recvEventArgs.Buffer == null || sendEventArgs.Buffer == null) { DataHoldingUserToken dToken = recvEventArgs.UserToken as DataHoldingUserToken; if (dToken != null) { this.theBufferManager.SetBuffer(dToken.BufferOffsetRecv, recvEventArgs); SocketListener.Log.WRN(string.Format("Receive SocketAsyncEventArgs buffer is null. reset buffer. Reuse later!! token:{0}, token_offset:{1}, recv_offset:{2}", dToken.TokenId, dToken.BufferOffsetRecv, recvEventArgs.Offset)); } dToken = sendEventArgs.UserToken as DataHoldingUserToken; if (dToken != null) { this.theBufferManager.SetBuffer(dToken.BufferOffsetSend, sendEventArgs); SocketListener.Log.WRN(string.Format("Send SocketAsyncEventArgs buffer is null. reset buffer. Reuse later!! token:{0}, token_offset:{1}, send_offset:{2}", dToken.TokenId, dToken.BufferOffsetSend, sendEventArgs.Offset)); } this.poolOfRecvEventArgs.Push(recvEventArgs); this.poolOfSendEventArgs.Push(sendEventArgs); continue; } break; } InitSocketAsyncEventArgs(ref recvEventArgs); InitSocketAsyncEventArgs(ref sendEventArgs); SocketListener.Log.MSG(string.Format("Start accept processing !! SocketAsyncEventArgs buffer offset. recv_offset:{0}, send_offset:{1}", recvEventArgs.Offset, sendEventArgs.Offset)); (recvEventArgs.UserToken as DataHoldingUserToken).CreateSessionId(); (recvEventArgs.UserToken as DataHoldingUserToken).RemoteIp = aToken.RemoteIp; (recvEventArgs.UserToken as DataHoldingUserToken).RemotePort = aToken.RemotePort; (recvEventArgs.UserToken as DataHoldingUserToken).IpEndPt = aToken.IpEndPt; (sendEventArgs.UserToken as DataHoldingUserToken).CreateSessionId(); (sendEventArgs.UserToken as DataHoldingUserToken).RemoteIp = aToken.RemoteIp; (sendEventArgs.UserToken as DataHoldingUserToken).RemotePort = aToken.RemotePort; (sendEventArgs.UserToken as DataHoldingUserToken).IpEndPt = aToken.IpEndPt; recvEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket; //recvEventArgs.SocketError = acceptEventArgs.SocketError; sendEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket; //sendEventArgs.SocketError = sendEventArgs.SocketError; (recvEventArgs.UserToken as DataHoldingUserToken).socketHandleNumber = (Int32)recvEventArgs.AcceptSocket.Handle; (sendEventArgs.UserToken as DataHoldingUserToken).socketHandleNumber = (Int32)sendEventArgs.AcceptSocket.Handle; // 이벤트 반납 aToken.RemoteIp = ""; aToken.RemotePort = 0; aToken.IpEndPt = null; acceptEventArgs.AcceptSocket = null; this.poolOfAcceptEventArgs.Push(acceptEventArgs); string strMsg; FACContainer.AddEx(recvEventArgs.AcceptSocket, recvEventArgs, sendEventArgs, out strMsg); if (!string.IsNullOrEmpty(strMsg)) { SocketListener.Log.WRN(recvEventArgs, string.Format("FACContainer AddEx - {0}!!", strMsg)); } this.DisplayConnectionInfo(); /// Accept 알림 보내기 SendMessageToClient(sendEventArgs, MessagePacketNameEnum.ACCPT); /// 수신 대기 StartReceive(recvEventArgs); } catch (Exception ex) { // REMOVE - KIMCG : 20140827 // Exception 발생시 재귀 호출로인해 Accept pool 에서 이벤트가 빠진다. -> 추후 이벤트 부족으로 작업불가함. // StartAccept(); // HandleBadAccept(acceptEventArgs); // REMOVE - END SocketListener.Log.ERR(string.Format("ProcessAccept - message:{0}\r\nstac_trace:{1}\r\nsource:{2}", ex.Message, ex.StackTrace, ex.Source)); } }
private bool ValidationCheckSocketAsyncEventArgs(string strFuncName, SocketAsyncEventArgs e) { string strRemoteIp = ""; int nRemotePort = 0; int nToken = 0; DataHoldingUserToken dToken = e.UserToken as DataHoldingUserToken; if (dToken != null) { strRemoteIp = dToken.RemoteIp; nRemotePort = dToken.RemotePort; nToken = dToken.TokenId; } else { AcceptOpUserToken aToken = e.UserToken as AcceptOpUserToken; strRemoteIp = aToken.RemoteIp; nRemotePort = aToken.RemotePort; nToken = aToken.TokenId; } if (e.AcceptSocket == null) { SocketListener.Log.ERR(string.Format("{0,-15}:{1}/{2}|{3} - AcceptSocket is null." , strRemoteIp , nRemotePort , nToken , strFuncName )); return(false); } //IPEndPoint remoteIpEndPoint = e.AcceptSocket.RemoteEndPoint as IPEndPoint; //if (remoteIpEndPoint == null) //{ // SocketListener.Log.ERR(string.Format("{0,-15}:{1}/{2}|{3} - RemoteIpEndPoint is null." // , strRemoteIp // , nRemotePort // , nToken // , strFuncName // )); // return false; //} SocketError sockErr = e.SocketError; if (sockErr != SocketError.Success) { SocketListener.Log.ERR(string.Format("{0,-15}:{1}/{2}|{3} - Socket error : {4}." , strRemoteIp , nRemotePort , nToken , strFuncName , sockErr )); return(false); } return(true); }