Xsocket Analysis One, start

Source: Internet
Author: User
Tags call back

Starting from a simple server hander analysis of Xsocket, first define a simple Echohandler inheritance Idatahandler

 Public class Implements idatahandler{    publicboolean  onData (inonblockingconnection NBC)                  Throws  IOException,                bufferunderflowexception,                maxreadsizeexceededexception {         = Nbc.readstringbydelimiter ("\ r \ n");          + "\ r \ n");          return true ;      }}

Then use this idatahandler to start the server

 Public classXsockettest { Public Static voidMain (string[] args)throwsunknownhostexception, IOException {//TODO auto-generated Method StubIServer SRV =NewServer (8090,NewEchohandler ()); //run it within the current thread.Srv.run ();//The call would not return//... or start it by using a dedicated thread//Srv.start ();//returns after the server has been started    }}

This implements a server that sends a string sent by the client back to the client, and the interface is simple.

Starting with the construction of the server, the server inherits from Iserver, and the class description is to receive the new connection, and the Inonblockingconnection processing agent to the Handler assigned to the server. The server contains dispatcher,dispatcher is responsible for performing IO operations, and each connection is assigned to a dispatcher. To handle application-related events such as OnData, onconnected, and so on, the corresponding callback function of the server's handler is called. During the server startup phase, the callback functions supported by handler are parsed by reflection, and the callback functions are tagged by implementing different interfaces such as Iconnecthandler, Idatahandler, and so on. Typically a server handler implements multiple handler interfaces. This section describes the overall structure of the xsocket, the main concepts are discussed, the latter will be detailed analysis.

The server overloads more than one constructor, which constructs the method called

    protectedServer (inetsocketaddress address, map<string, object> options, Ihandler handler, Sslcontext Sslcontext,BooleanSslon,intBacklogintMinpoolsize,intMaxpoolsize,intTaskqueuesize)throwsunknownhostexception, IOException {defaultworkerpool=NewWorkerpool (minpoolsize, Maxpoolsize, taskqueuesize); Workerpool=Defaultworkerpool; if(Sslcontext! =NULL) {acceptor= Connectionutils.getioprovider (). Createacceptor (NewLifecyclehandler (), address, backlog, options, Sslcontext, Sslon); } Else{acceptor= Connectionutils.getioprovider (). Createacceptor (NewLifecyclehandler (), address, backlog, options); } localhostname=acceptor.getlocaladdress (). GetHostName (); LocalPort=Acceptor.getlocalport ();    SetHandler (handler); }

The main parameters are port, Ihandler, whether SSL is supported, working thread pool parameters, other than what we give are the default values. Creating a worker thread pool first Workpool,workerpool inheriting from the Threadpoolexecutor,workpool constructor requires a queue that holds the task before the task executes, and this is Workerpoolawarequeue Extends Linkedblockingqueue<runnable> This workerpoolawarequeue rewritten the offer function to join the log, A small optimization occurs when the online pool does not have idle threads and returns False when the maximum number of threads is not reached to force the start of a new worker thread instead of waiting in the task queue.

Then create the acceptor. This creates a lifecyclehandler (important, later), implements the Iioacceptorcallback interface, and defines the oncoonected () method in the interface to callback when the acceptor binds to the socket or receives the request. Connectionutils provides a handy way to set up and bytebuffer operations, where static variables Ioprovider define various parameters of the socket IO, createacceptor function calls

New Ioacceptor (callback, address, backlog, isreuseaddress);

The Ioacceptor constructor is as follows

     PublicIoacceptor (Iioacceptorcallback callback, inetsocketaddress address,intBacklog, Sslcontext Sslcontext,BooleanSslon,Booleanisreuseaddress)throwsIOException { This. Callback =callback;//This callback is just said Lifecyclehandler This. Sslcontext =Sslcontext;  This. Sslon =Sslon; Log.fine ("Try to bind server on" +address); //create a new server socketServerchannel =Serversocketchannel.open ();//Construction Serverchannelassert(Serverchannel! =NULL); Serverchannel.configureblocking (true); Serverchannel.socket (). Setsotimeout (0);//Accept method never times outServerchannel.socket (). setreuseaddress (isreuseaddress); Whether the port can be reused when the channel is closed but still aliveTry{serverchannel.socket (). Bind (address, backlog); Build Iosocketdispatcherpool Dispatcherpool=NewIosocketdispatcherpool ("SRV" +Getlocalport (), ioprovider.getserverdispatcherinitialsize ()); } Catch(Bindexception Be) {serverchannel.close (); Log.warning ("Could not bind server to" + Address + ". Reason: "+dataconverter.tostring (BE)); ThrowBe ; }    }

Iosocketdispatcherpool was created in the constructor, and two iosocketdispatcher were instantiated and run when the pool was built

 for(inti = currentrunning; i < size; i++) {Iounsynchronizedmemorymanager Memorymanager=NULL; if(preallocation) {
Memory management, using pre-allocated memory method first regardless of Memorymanager=Iounsynchronizedmemorymanager.createpreallocatedmemorymanager (preallocationsize, BufferMinsize, UseDirect); } Else{Memorymanager =Iounsynchronizedmemorymanager.createnonpreallocatedmemorymanager (Usedirect); } Iosocketdispatcher Dispatcher=NewIosocketdispatcher (Memorymanager, name + "#" +i); Dispatchers.addlast (dispatcher); Thread T=NewThread (Dispatcher); T.setdaemon (true); T.start (); for(Iiodispatcherpoollistener listener:listeners) {listener.ondispatcheradded (dispatcher); }}

The Iosocketdispatcher constructor called Selector = Selector.open (); The Run method is as follows

     Public voidrun () {//set thread name and attach dispatcher ID to threadThread.CurrentThread (). SetName (name);                Threadbound_id.set (ID); Direct_call_counter.set (0); if(Log.isloggable (level.fine)) {Log.fine ("Selector" + name + "Listening ..."); }        intHandledtasks = 0;  while(Isopen.get ()) {Try {                intEventCount = Selector.select (5000); Handledtasks=performregisterhandlertasks ();//Handling registration tasks, important handledtasks+=performkeyupdatetasks ();//Handling key update tasks, importantif(EventCount > 0{Handlereadwritekeys ();//handling read-write events, important} handledtasks+=performderegisterhandlertasks (); Checkforlooping (EventCount+handledtasks, Lasttimewokeup); } Catch(Throwable e) {//eat and log exception                if(Log.isloggable (level.fine)) {Log.fine ("[" + Thread.CurrentThread (). GetName () + "] exception occured while processing. Reason "+dataconverter.tostring (e)); }            }        }         for(Iosockethandler sockethandler:getregistered ()) {sockethandler.onderegisteredevent (); }        Try{selector.close (); } Catch(Exception e) {//eat and log exception            if(Log.isloggable (level.fine)) {Log.fine ("Error occured by close selector within TearDown" +dataconverter.tostring (e)); }        }    }

Back to the original main method, where Srv.run () was called; The run function finally calls the accept function of acceptor

    Private voidAccept () { while(Isopen.get ()) {Try {                //Blocking Accept CallSocketchannel channel =serverchannel.accept (); //Create IosockethandlerIosocketdispatcher Dispatcher =Dispatcherpool.nextdispatcher (); Iochainablehandler Iohandler= Connectionutils.getioprovider (). Createiohandler (false, Dispatcher, channel, Sslcontext, Sslon); //Notify Call backcallback.onconnectionaccepted (Iohandler); Acceptedconnections++; } Catch(Exception e) {//If Acceptor is running (<socket>.close () causes this any//thread currently blocked in accept () would throw a socketexception)                if(Serverchannel.isopen ()) {log.warning ("Error occured while accepting connection:" +dataconverter.tostring (e)); }            }        }    }

It is important to complete the startup of the server, primarily starting a acceptor thread and two dispatcher threads.

Xsocket Analysis One, start

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.