void OnAcceptAsync(object _obj, SocketAsyncEventArgs _acceptArgs) { if (Protocol.DEBUG_SLEEP_ACCEPT) { System.Threading.Thread.Sleep(10); } identity++; Console.WriteLine("[{0}]OnAcceptAsync (callback) New Client connect", identity); //--------------------------------------- //신규접속 유저 신규소켓 > Pool에서 하나 꺼내서 달아주기. //신규유저 받는 전용 소켓은 재등록 해주고... //--------------------------------------- Socket _clientSocket = _acceptArgs.AcceptSocket; Socket _acceptSocket = acceptSocket; _acceptArgs.AcceptSocket = null; bool _bAcceptSocketAlive = _acceptSocket.AcceptAsync(_acceptArgs); if (Protocol.DEBUG) { Console.WriteLine((_acceptSocket == acceptSocket) + ":" + (acceptArgs == _acceptArgs)); } if (_bAcceptSocketAlive == false) { //접속대기 등록하자마자 -> 신규유저 바로 접속은 없다 //50 대기중 발생안함 //100 대기중 발생안함 //120 대기중 발생안함. //03-10 200회 테스트 했는데 안들어옴... //절대 안들어올듯... Console.WriteLine("OnAcceptAsync >> .AcceptAsync @@@@ {0} 신규유저접속받기 등록하자마사 > 바로접속", identity); OnAcceptAsync(_acceptSocket, _acceptArgs); } //--------------------------------------- // pool -> client setting infomation //--------------------------------------- CUserToken _token = listFreeUser.Dequeue(); //if (_token.bProblemData) //{ // //_token 문제가 있는놈이다 // // > 뎅글링 클래스로 나둬버림... // // > GC가 호출해감.... // //새것으로 다시 뺴오자..~~~ // _token = listFreeUser.Dequeue(); //} _token.socket = _clientSocket; listConnectUser.Add(_token); _token.identityID = identity; //------------------------------------------------------------------- // 이중으로 ReceiveAsync 등록시 오류 //_bReceive = _clientSocket.ReceiveAsync(_token.receiveArgs); //_bReceive = _clientSocket.ReceiveAsync(_token.receiveArgs); < -이놈이 발생... //System.InvalidOperationException: '"이 SocketAsyncEventArgs 인스턴스를 사용하여 비동기 소켓 작업이 이미 진행되고 있습니다.";' // // 서버가 오류발생.... // // 클라에 오류가 발생 전달... 클라를 닫으면 아래의 메세지가 그제서야 들어옴... //System.InvalidOperationException: "이 SocketAsyncEventArgs인스턴스를 사용하여 비동기 소켓 작업이 이미 진행되고 있습니다."; //System.Net.Sockets.SocketAsyncEventArgs.StartOperationCommon(Socket socket) //System.Net.Sockets.Socket.ReceiveAsync(SocketAsyncEventArgs e) //TimeServer10.Program.OnAcceptAsync(Object _obj, SocketAsyncEventArgs _acceptArgs) 파일 D:\devtool\study\study\_Lesson_NetStep1\20_TcpAsyncSample\FreeNetTest2\TimeServer10\TimeServer10\Program.cs:줄 123 //System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e) //System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) //System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags) //System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped * nativeOverlapped) //System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped * pOVERLAP) //------------------------------------------------------------------- bool _bReciveSocketAlive = _clientSocket.ReceiveAsync(_token.receiveArgs); //_bReceive = _clientSocket.ReceiveAsync(_token.receiveArgs); if (_bReciveSocketAlive == false) { //50 대기중 발생안함 //100 대기중 발생안함 //120 대기중 발생안함. //등록하자마자 바로 데이타 받음... // //서버가 과부하 상태에서 신규 유저 접속하자 마자 바로 종료하는 경우... //100% 발생함...데이타 대량으로 오고 가는중에 발생.... // > 접속 종료에 대한 메세지를 받은 것임.. ㅎㅎㅎ // 접속 -> 대기중... 음... 바로 -> 바로 종료.... 발생....(종료 메세지) Console.WriteLine("[{0}]OnAcceptAsync >> .ReceiveAsync @@@@ {0}/{1} 신규유저받고, 바로 메세지 받음", _token.identityID, _token.socket.Connected, _token.receiveArgs.BytesTransferred, _token.receiveArgs.LastOperation, _token.receiveArgs.SocketError); OnReceiveAsync(_clientSocket, _token.receiveArgs); } Console.WriteLine("[{0}]connect free:{1} use:{2}", _token.identityID, listFreeUser.Count, listConnectUser.Count); }
void OnReceiveAsync(object _obj, SocketAsyncEventArgs _receiveArgs) { CUserToken _token = _receiveArgs.UserToken as CUserToken; int _debugWorkNum = _token.GetWorkNum(); if (Protocol.DEBUG) { Console.WriteLine("[{0}]OnReceiveAsync (callback) >> socket:{1} BytesTransferred:{2} LastOperation:{3} SocketError:{4}", _token.identityID + "/" + _debugWorkNum, _token.socket.Connected, _receiveArgs.BytesTransferred, _receiveArgs.LastOperation, _receiveArgs.SocketError); } if (_receiveArgs.LastOperation == SocketAsyncOperation.Receive && _receiveArgs.SocketError == SocketError.Success && _receiveArgs.BytesTransferred > 0) { SocketAsyncEventArgs _sendArgs = _token.sendArgs; Socket _clientSocket = _token.socket; //--------------------------------------- // Client -> Socket -> Receive //--------------------------------------- int _transferred = _receiveArgs.BytesTransferred; byte[] _buffer2 = new byte[_transferred]; Array.Copy(_receiveArgs.Buffer, _receiveArgs.Offset, _buffer2, 0, _transferred); if (Protocol.DEBUG) { Console.WriteLine(" [{0}] >> 등록전 _socket.Connected:{1} _transferred:{2}", _token.identityID, _clientSocket.Connected, _transferred); } bool _bDebugRececiveTrueAfter = false; if (Protocol.DEBUG_SLEEP_PACKET) { System.Threading.Thread.Sleep(10); } if (_clientSocket.Connected == false) { _bDebugRececiveTrueAfter = true; Console.WriteLine("@@@@ 등록전 @@@@"); Console.WriteLine(" [{0}] >> 등록전 _socket.Connected:{1} _transferred:{2}", _token.identityID, _clientSocket.Connected, _transferred); } if (Protocol.DEBUG_SLEEP_PACKET) { System.Threading.Thread.Sleep(10); } bool _bReceiveAsync = _clientSocket.ReceiveAsync(_receiveArgs); if (Protocol.DEBUG_SLEEP_PACKET) { System.Threading.Thread.Sleep(10); } //_bReceive = _socket.ReceiveAsync(_receiveArgs); if (Protocol.DEBUG) { Console.WriteLine(" [{0}] >> 등록후 _socket.Connected:{2} _bReceive:{1}", _token.identityID, _bReceiveAsync, _clientSocket.Connected); } if (_bDebugRececiveTrueAfter) { Console.WriteLine("@@@@ 등록후 @@@@"); Console.WriteLine(" [{0}] >> 등록전 _socket.Connected:{1} _transferred:{2}", _token.identityID, _clientSocket.Connected, _transferred); } //-------------------------------------- //중간에 끼워들어옴... 음... if (_clientSocket.Connected == false) { //갑자기 종료하면 발생함.... //20개에서도 발생함... Console.WriteLine(" [{0}]OnReceiveAsync .ReceiveAsync @@@@ 파싱중~~ 재등록후(소켓꺼짐) {1}/{2}/{3}/{4}", _token.identityID + "/" + _debugWorkNum, _token.socket.Connected, _receiveArgs.BytesTransferred, _receiveArgs.LastOperation, _receiveArgs.SocketError); Disconnect(" @@@@@(" + _debugWorkNum + ") >> OnReceiveAsync 파싱후 재등록후(소켓꺼짐)", _token); return; } if (_bReceiveAsync == false) { //등록하자마사 바로 데이타 받음... Console.WriteLine(" [{0}] #### OnReceiveAsync > _socket.ReceiveAsync 메세지 받기(2) 등록하자마사 바로 받음.{1}", _token.identityID, _clientSocket.Connected); OnReceiveAsync(null, _receiveArgs); } //Data Parse and Send... string _text = Encoding.ASCII.GetString(_buffer2, 0, _transferred); if (Protocol.DEBUG_PACKET) { Console.WriteLine("[{0}]:{1}", _token.identityID + ":" + _debugWorkNum, _text); } string _response = string.Empty; if (_text.ToLower().Equals("get time")) { _response = "[C <- S] OK Time Server9"; } else { _response = "[C <- S] Fail"; } byte[] _sendBuffer2 = Encoding.ASCII.GetBytes(_response); int _sendSize = _sendBuffer2.Length; Array.Copy(_sendBuffer2, 0, _sendArgs.Buffer, _sendArgs.Offset, _sendSize); _sendArgs.SetBuffer(_sendArgs.Offset, _sendSize); //이부분에서 130개를 넘어가면 오류가 메모리 오류... //그 근처에서 메모리 오류가 먼저 발생해준다. (메모리는 충분한데... win7내 컴에서 종종 나타난다...) //2G까지만 (Person win7) //bool _bSend = true; //try //{ // _bSend = _socket.SendAsync(_sendArgs); //} //catch (Exception _e) //{ // Console.WriteLine(" >>> OnReceiveAsync _socket.SendAsync _e:{0}", _e); // Disconnect(" <<<< ***보낼려고 하는데 어 아직 안보낸것이 있네...***", _token, true); // return; //} //if (Protocol.DEBUG) Console.WriteLine("[{0}] _bSend {1} {2}", _token.identityID, _bSend, _socket.Connected); // // //if (_socket.Connected == false) //{ // Disconnect(" <<<< 보낼때1", _token); // return; //} //if (_bSend == false) //{ // Console.WriteLine("[{0}] #### OnReceiveAsync _socket.SendAsync -> 보내기(1) 등록하자마사 바로 받음.{1}", _token.identityID, _socket.Connected); // OnSendAsync(_socket, _sendArgs); //} } else { Console.WriteLine("[{0}]OnReceiveAsync [정상종료] >>> :{1} :{2} :{3} :{4}", _token.identityID + "/" + _debugWorkNum, _token.socket.Connected, _receiveArgs.BytesTransferred, _receiveArgs.LastOperation, _receiveArgs.SocketError ); //if (_token.socket != null) //{ // bool _bReceive = _token.socket.ReceiveAsync(_receiveArgs); // Console.WriteLine(" _bReceive:" + _bReceive); //} Disconnect("[정상종료]", _token); } }