private void ReleaseSocket(ASSocket socket) { lock (this) { int iocount = socket.exitIO(); if (0 == iocount) { // 이 경우에는 Dispose()를 위해 Close()할 필요는 없다? //socket.tcpclient.GetStream().Close(); //socket.tcpclient.Close(); //socket.sendlist.Clear(); // 객체파괴가 어떻게 일어날지 모르니, desc는 값을 복사해서 사용하자. theSockets.Remove(socket.theDESC.managedID); ASSOCKDESC desc = new ASSOCKDESC(); desc.createTick = socket.theDESC.createTick; desc.managedID = socket.theDESC.managedID; desc.theSender = socket.theDESC.theSender; // socket에 대해 메모리 풀링이 필요하다면, clone()과 아래 함수가 풀링에 대해 어떻게 처리할지 담당하면된다. // socket이 구체적으로 어떤 타입인지에 따라 풀링매니저가 달라져야 하기 때문에, asio계층에선 담당하지 않는다. theReceiver.notifyReleaseSocket(desc, socket); } } }
public int disconnectSocket(ASSOCKDESC sockdesc) { lock (this) { // 단순히 Close하면되는것인가? // bugfix 찾지못한경우 널이 반환되는게 아니라 예외가 던져진다. // theSockets만 쓰레드컨트롤하면된다. ASSocket aSocket; try { aSocket = theSockets[sockdesc.managedID]; } catch (Exception exe) { return((int)MyErrorCode.NoSuchSocket); } if (aSocket.theDESC.createTick != sockdesc.createTick) { return((int)MyErrorCode.NoSuchSocket); } aSocket.tcpclient.GetStream().Close(); aSocket.tcpclient.Close(); } return(0); }
public int DisconnectSocket(ASSOCKDESC sockdesc) { lock (this) { // 단순히 Close하면되는것인가? // bugfix 찾지못한경우 널이 반환되는게 아니라 예외가 던져진다. // theSockets만 쓰레드컨트롤하면된다. AsyncSocket aSocket; try { aSocket = Sockets[sockdesc.ManagedID]; } catch (Exception /*ex*/) { return((int)MyErrorCode.NoSuchSocket); } if (aSocket.Description.CreateTick != sockdesc.CreateTick) { return((int)MyErrorCode.NoSuchSocket); } aSocket.TCPClient.GetStream().Close(); aSocket.TCPClient.Close(); } return(0); }
public ASSocket() { iocount = 0; theDESC = new ASSOCKDESC(); theDESC.theSender = null; theDESC.managedID = retrieveUID(); theDESC.createTick = System.Environment.TickCount; }
public AsyncSocket() { IOCount = 0; Description = new ASSOCKDESC(); Description.NetSender = null; Description.ManagedID = RetrieveUID(); Description.CreateTick = System.Environment.TickCount; }
// c#에선 TcpListener.AcceptTcpClient가 반환하는 TcpClient객체레퍼런스를 넘겨줘야한다. // 즉 c++에선 int 값을 넘겨줬지만, c#에선 TcpClient 이 객체를 기본 베이스로 사용해야 한다. public int RegisterSocket(TcpClient acceptedclient, AsyncSocket prototype) { // 락을 걸어야하나? lock (this) { // 개체하나를 클론하고 AsyncSocket aSocket = prototype.Clone() as AsyncSocket; aSocket.SetTcpClient(acceptedclient); aSocket.Description.NetSender = this; // 관리리스트에 등록 - need lock Sockets.Add(aSocket.Description.ManagedID, aSocket); // 리시버에게 // 객체파괴가 어떻게 일어날지 모르니, desc는 값을 복사해서 사용하자. ASSOCKDESC desc = new ASSOCKDESC(); desc.CreateTick = aSocket.Description.CreateTick; desc.ManagedID = aSocket.Description.ManagedID; desc.NetSender = aSocket.Description.NetSender; NetReceiver.NotifyRegisterSocket(desc, aSocket.RemoteAddress); // 1.1 async 버전으로 업그레이드 aSocket.EnterIO(); // key saea얻어오기 실패하면 메모리부족이기 때문에, 프로세스를 죽여야한다. SocketAsyncEventArgs readEventArgs = AsioManager.RetreiveEventArgs();// new SocketAsyncEventArgs();//= saeaPool.pop(); // saeaPool from the ASIOManager try { readEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); readEventArgs.UserToken = aSocket; bool willRaiseEvent = aSocket.TCPClient.Client.ReceiveAsync(readEventArgs); if (!willRaiseEvent) { ProcessReceive(readEventArgs); // 위에서 releaseSocket이 되면, 아래 예외처리는 수행되지 않는다. } } catch (Exception ex) { Console.WriteLine(DateTime.Now.ToString() + " - registerSocket " + ex.Message); // releasesocket을 수정하지 말고 각 문맥에서 releaseSAEA를 호출하자 if (null != readEventArgs) { readEventArgs.Completed -= IO_Completed; AsioManager.ReleaseSAEA(readEventArgs); } ReleaseSocket(aSocket); } } return(0); }
// 받은 내용을 어떻게 처리할지는 이 함수를 재정의해서 처리하시오! public virtual void handleReceived(int length, byte[] data, int offset, INetworkReceiver receiver) { // todo 보통 아래 receiver.notifyMessage 함수에서 프로토콜에 맞는 객체를 생성하면 될것이다. // 생성은 쓰레드제어없이 가능하게하고, enqueuing을 쓰레드제어하면 된다. // 객체파괴가 어떻게 일어날지 모르니, desc는 값을 복사해서 사용하자. ASSOCKDESC desc = new ASSOCKDESC(); desc.createTick = theDESC.createTick; desc.managedID = theDESC.managedID; desc.theSender = theDESC.theSender; receiver.notifyMessage(desc, length, data, offset); }
private void ResultConnect(IAsyncResult ar) { ConnectFrame connectFrame = (ar.AsyncState as ConnectFrame); ASSOCKDESC desc = new ASSOCKDESC(); desc.createTick = connectFrame.socket.theDESC.createTick; desc.managedID = connectFrame.socket.theDESC.managedID; desc.theSender = connectFrame.socket.theDESC.theSender; try { connectFrame.socket.tcpclient.EndConnect(ar); theReceiver.notifyConnectingResult(connectFrame.reqID, desc, true, null); // 2012-09-19 bugfix PostingRead // 1.1 async 버전으로 업그레이드 connectFrame.socket.enterIO(); SocketAsyncEventArgs readEventArgs = asiomanager.RetreiveSAEA();// new SocketAsyncEventArgs();//= saeaPool.pop(); // saeaPool from the ASIOManager try { readEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); readEventArgs.UserToken = connectFrame.socket; bool willRaiseEvent = connectFrame.socket.tcpclient.Client.ReceiveAsync(readEventArgs); if (!willRaiseEvent) { ProcessReceive(readEventArgs); // 위에서 releaseSocket이 되면, 아래 예외처리는 수행되지 않는다. } } catch (Exception ex) { // releasesocket을 수정하지 말고 각 문맥에서 releaseSAEA를 호출하자 if (null != readEventArgs) { readEventArgs.Completed -= IO_Completed; asiomanager.ReleaseSAEA(readEventArgs); } ReleaseSocket(connectFrame.socket); } } catch (Exception ex) { lock (this) { theSockets.Remove(desc.managedID); } theReceiver.notifyConnectingResult(connectFrame.reqID, desc, false, ex); connectFrame.socket.tcpclient = null; } }
public int postingSend(ASSOCKDESC sockdesc, int length, byte[] data) { // postingSend, ReleaseSocket(다른 워커쓰레드에서 ResultRead, ResultWrite에서 을 쓰레드락걸지 않으면, // aSocket.sendlist를 위해서라도 락을 걸어야한다. lock (this) { // bugfix 찾지못한경우 널이 반환되는게 아니라 예외가 던져진다. ASSocket aSocket; try { aSocket = theSockets[sockdesc.managedID]; } catch (Exception exe) { return((int)MyErrorCode.NoSuchSocket); } if (aSocket.theDESC.createTick != sockdesc.createTick) { return((int)MyErrorCode.NoSuchSocket); } // asiomanager 생성시 io 크기보다 큰 센드 요청은 할수 없다. if (asiomanager.IOMAXSIZE < length || 0 >= length) { return((int)MyErrorCode.SizeError); } // sendlist쓰지말고 곧바로 보내버리자!!! SocketAsyncEventArgs writeEventArgs = asiomanager.RetreiveSAEA(); if (null == writeEventArgs) { // temp code critical outofmemory return((int)MyErrorCode.OutOfMemory); } aSocket.enterIO(); try { // send의 경우 setbuffer 자체가 보낼 버퍼를 지정하는것이다... setbuffer를 다시한번해서 하는게 안전할까? writeEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); writeEventArgs.SetBuffer(writeEventArgs.Buffer, writeEventArgs.Offset, length); Array.Copy(data, 0, writeEventArgs.Buffer, writeEventArgs.Offset, length); writeEventArgs.UserToken = aSocket; bool willRaiseEvent = aSocket.tcpclient.Client.SendAsync(writeEventArgs); if (!willRaiseEvent) { ProcessSend(writeEventArgs); } } catch (Exception ex) { Console.WriteLine(DateTime.Now.ToString() + " - postingSend " + ex.Message); if (null != writeEventArgs) { writeEventArgs.Completed -= IO_Completed; asiomanager.ReleaseSAEA(writeEventArgs); } ReleaseSocket(aSocket); } } return(0); }
public int releaseASSOCKDESC(ASSOCKDESC sockdesc) { ASSocket.releaseUID(sockdesc.managedID); return(0); }
public int ReleaseASSOCKDESC(ASSOCKDESC sockdesc) { AsyncSocket.ReleaseUID(sockdesc.ManagedID); return(0); }