//__END variables for real app____________________________________________ //____________________________________________________________________________ // Create uninitialized SocketClient instance. public SocketClient(SocketClientSettings theSocketClientSettings) { if (Program.watchProgramFlow == true) //for testing { Program.testWriter.WriteLine("SocketClient constructor"); } this.socketClientSettings = theSocketClientSettings; this.prefixHandler = new PrefixHandler(); this.messageHandler = new MessageHandler(); this.messagePreparer = new MessagePreparer(); this.bufferManager = new BufferManager(this.socketClientSettings.BufferSize * this.socketClientSettings.NumberOfSaeaForRecSend * this.socketClientSettings.OpsToPreAllocate, this.socketClientSettings.BufferSize * this.socketClientSettings.OpsToPreAllocate); this.poolOfRecSendEventArgs = new SocketAsyncEventArgsPool(this.socketClientSettings.NumberOfSaeaForRecSend); this.poolOfConnectEventArgs = new SocketAsyncEventArgsPool(this.socketClientSettings.MaxConnectOps); this.theMaxConnectionsEnforcer = new Semaphore(this.socketClientSettings.MaxConnections, this.socketClientSettings.MaxConnections); this.counterForLongTest = new Semaphore(this.socketClientSettings.ConnectionsToRun, this.socketClientSettings.ConnectionsToRun); Init(); }
//____________________________________________________________________________ // This method is called when we need to create a new SAEA object to do //connect operations. The reason to put it in a separate method is so that //we can easily add more objects to the pool if we need to. //You can do that if you do NOT use a buffer in the SAEA object that does //the connect operations. private SocketAsyncEventArgs CreateNewSaeaForConnect(SocketAsyncEventArgsPool pool) { //Allocate the SocketAsyncEventArgs object. SocketAsyncEventArgs connectEventArg = new SocketAsyncEventArgs(); //Attach the event handler. Since we'll be using this //SocketAsyncEventArgs object to process connect ops, //what this does is cause the calling of the ConnectEventArg_Completed //object when the connect op completes. connectEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); ConnectOpUserToken theConnectingToken = new ConnectOpUserToken(pool.AssignTokenId() + 10000); connectEventArg.UserToken = theConnectingToken; return(connectEventArg); //You may wonder about the buffer of this object. If you //decide to use objects from one pool to do connect operations, and //a separate pool of SAEA objects to do send/receive, then //there is NO NEED to assign a buffer to this SAEA object for connects. //But, if you want to //use this SAEA object to do connect, send, receive, and disconnect, //then you will need a buffer for this object. //Working with the buffer is different in the client vs the server, due //to the way that ConnectAsync works. //You would need to think about whether to do the initial call of //BufferManager.SetBuffer here, or do it in ProcessConnect method. //If a SocketAsyncEventArg object has a buffer already set before //the ConnectAsync method is called, then the contents of the buffer will //be sent immediately upon connecting, without your calling StartSend(). //Read that sentence again. //So you could only call BufferManager.SetBuffer here if you are sure the //client will always do a send operation first, and the data will be //ready when the connection is made. If you want to have the //option of doing a receive operation first, then wait and set the buffer //after the connect operation completes. //If you decide to use that design, then you will need to call the //BufferManager's FreeBuffer method, to //null the buffer again before putting it back in the pool. FreeBuffer would //probably need to be called in the ProcessDisconnectAndCloseSocket method. }