public void Initialize() { this.max_connections = 10000; this.buffer_size = 1024; this.buffer_manager = new BufferManager(this.max_connections * this.buffer_size * this.pre_alloc_count, this.buffer_size); this.receive_event_args_pool = new SocketAsyncEventArgsPool(this.max_connections); this.send_event_args_pool = new SocketAsyncEventArgsPool(this.max_connections); this.buffer_manager.InitBuffer(); SocketAsyncEventArgs arg; for (int i = 0; i < this.max_connections; i++) { // 동일한 소켓에 대고 send, reciev를 하므로 // user token은 세션별로 하나씩만 만들어 놓고 // receive, send EventArgs에서 동일한 token을 참조하도록 구성합니다. CUserToken token = new CUserToken(); // receive pool { arg = new SocketAsyncEventArgs(); arg.Completed += new EventHandler <SocketAsyncEventArgs>(receive_completed); arg.UserToken = token; this.buffer_manager.SetBuffer(arg); this.receive_event_args_pool.Push(arg); } // send pool { arg = new SocketAsyncEventArgs(); arg.Completed += new EventHandler <SocketAsyncEventArgs>(send_completed); arg.UserToken = token; this.buffer_manager.SetBuffer(arg); this.send_event_args_pool.Push(arg); } } }
// Initializes the server by preallocating reusable buffers and // context objects. These objects do not need to be preallocated // or reused, but it is done this way to illustrate how the API can // easily be used to create reusable objects to increase server performance. // public void Initialize() { // receive버퍼만 할당해 놓는다. // send버퍼는 보낼때마다 할당하든 풀에서 얻어오든 하기 때문에. //int pre_alloc_count = 1; //var totalBytes = ServerOpt.MaxConnectionCount * ServerOpt.ReceiveBufferSize * pre_alloc_count; //BufferManager buffer_manager = new BufferManager(totalBytes, ServerOpt.ReceiveBufferSize); //buffer_manager.InitBuffer(); // receive버퍼만 할당해 놓는다. // send버퍼는 보낼때마다 할당하든 풀에서 얻어오든 하기 때문에. const int pre_alloc_count = 1; int argsCount = ServerOpt.MaxConnectionCount * pre_alloc_count; int argsBufferSize = ServerOpt.ClientReceiveBufferSize; ReceiveEventArgsPool = new SocketAsyncEventArgsPool(); ReceiveEventArgsPool.Init(SocketAsyncEventArgsPoolBufferMgrType.Concurrent, argsCount, argsBufferSize); SendEventArgsPool = new SocketAsyncEventArgsPool(); // preallocate pool of SocketAsyncEventArgs objects SocketAsyncEventArgs arg; for (int i = 0; i < ServerOpt.MaxConnectionCount; i++) { // 더이상 UserToken을 미리 생성해 놓지 않는다. // 다수의 클라이언트에서 접속 -> 메시지 송수신 -> 접속 해제를 반복할 경우 문제가 생김. // 일단 on_new_client에서 그때 그때 생성하도록 하고, // 소켓이 종료되면 null로 세팅하여 오류 발생시 확실히 드러날 수 있도록 코드를 변경한다. // receive pool { //Pre-allocate a set of reusable SocketAsyncEventArgs arg = new SocketAsyncEventArgs(); arg.Completed += new EventHandler <SocketAsyncEventArgs>(ReceiveCompleted); arg.UserToken = null; // assign a byte buffer from the buffer pool to the SocketAsyncEventArg object //buffer_manager.SetBuffer(arg); // add SocketAsyncEventArg to the pool ReceiveEventArgsPool.Push(arg); } // send pool { //Pre-allocate a set of reusable SocketAsyncEventArgs arg = new SocketAsyncEventArgs(); arg.Completed += new EventHandler <SocketAsyncEventArgs>(SendCompleted); arg.UserToken = null; // send버퍼는 보낼때 설정한다. SetBuffer가 아닌 BufferList를 사용. arg.SetBuffer(null, 0, 0); // add SocketAsyncEventArg to the pool SendEventArgsPool.Push(arg); } } ReserveClosingProc.Start(ServerOpt.ReserveClosingWaitMilliSecond); }