关键词不能为空

当前您在: 主页 > 英语 >

xsocket使用指南【官方文档翻译】

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-15 14:26
tags:

-

2021年2月15日发(作者:杀害)


核心功能



支持面向流通信主要抽象是


Connection


接口。


通过


IBlockingConnection


或者


IN onblockingConnection


对象进行数据的读写。在

< br>record


或者


bulk


状态 中,


Connection


对象提供了对于特定数据类型的几个 方便方法。



Connection


实 现了



包中的


GatheringByt eChannel



WritableByteChannel


接口,如果


InputStream


或 者


OutputStream


对象被需要,可

< br>以使用


utStream()



putStream()


包装


channel


对象,因为


经典的流只有在


IBlockingConnection

映射到经典的


InputStream


中时才有阻塞行


为。



提供的其他类型方法主要是控制连接 行为和获取连接信息的方法。比如,远


程链接点信息可以获取到,


连接的数据冲刷行为可以被控制。


这些方法都不是线


程安全的 。




IBlockingConne ction


不同的是,


INonBlockingConnec tion


在调用


read


方法


直接返回。



IDataHandler


对象赋给


INonBlockingConnection

< p>
对象可以使其在新


数据到来时被通知。当对应的事件发生时,


IDataHandler


对象的回调函数会被调


用 。除了


IDataHandler


也存在


IConnectionHandler


对象。


< p>
服务器端在


INonblockingConnection


接口上处理接入连接。




1


、示例:简单


TCP


服务器



首先定义实现了需要的接口(比如,


IDat aHandler



IConnectHandler



IIdleTimeoutHandler


或 者


IConnectionTimeoutHandler


)< /p>


,这个


DataHandler


会在从< /p>


连接上接收到数据时被调用。



classEchoHandler implements IDataHandler {


publicbooleanonData(INon BlockingConnectionnbc)



throwsIOException,



BufferUnderflowException,



MaxReadSizeExceededException {







String data = ringByDelimiter(


(data +


return true;




}


}


然后创建一个服务器实例,并 将上面的


DataHandler


赋给它



// creates the server by passing over the port number & handler


IServersrv = new Server(8090, new EchoHandler());



// run it within the current thread.



();



// the call will not return



// ... or start it by using a dedicated thread


专用线程



(); // returns after the server has been started

< br>与


run


方法对应的,服务器的


start


方法创建一个专用的线程来运行服务器。


start


方法在内部阻塞知道服务器启动,


为了确保服务器在执行其他进 一步操作前


被启动,这是比较好的方法。


执行服务器的


close


方法来优雅的关闭服务器。就像其 他面向连接的框架,


服务器实现了


le


接口




2



DataHandler



onDat a


方法的语义分析



IDataHan dler



onData


方法会在数据 分片被接收后直接调用。要注意的是,


在网络层,数据可以被分解成若干个


TCP


片段也可能被组合打包成一个


TCP



文。


在客户端执行类似于

(



hello



)


的写操作,


并不意味着一个


TCP


报文到达服务器端。


xSocket

通过内部的读缓冲区缓冲接收到的网络数据来隐藏


网络行为。



在没有足够数据可用的情况下,数据分片会导致


NonBl ockingConnection



read


方法抛出


BufferUnderflowException


异常。根据运行模式,在一个挂起的


onData


方法 调用期间没有数据会在网络层被收到。通过使用


NONTHREADED


模式,


xSocket


的内部网络

I/O


线程执行


onDataMethod


所以不能读取网络层数据。



BufferUnder flowException


异常不处理是一个惯用的方法,


x Socket


会在


onData


方法返 回时处理这个异常。



classEchoHandler implements IDataHandler {







// this method will be called each time when data fragments have been


received


publicbooleanonData(INonBlockingConnectionnbc)



throwsIOException,


ClosedChannelException,



BufferUnderflowException,



MaxReadSizeExceededException {










// don't handle the BufferUnderflowException, xSocket will swallow it



byte[] bytes = tesByLength(500);










//...



return true;






}


}


因为没有读到的数据在


xSock et


的内部缓冲内,


onData


方法 会被再次调用。


也就是说,


onData


方法会在没有新的网络数据包到达时调用,


因为


xSocke t


的内


部读缓冲区是不空的。这个循环会在内部缓冲区为空或者


onData


方法读不到数


据时结束。


xSocket


在每次调用


onDat a


方法后检查内部读缓冲区是否被修改


(新

的网络数据到达,或者数据被读出)


,从而决定是不是要再次调用

< br>onData




当连接关闭时 ,


onData


方法也会被调用。与处理缓冲区的


underflow


异常一


样,

closedChannelException


也是不处理的,实现


IDisconnectHandler


来检测连接


关闭。



3


、写阻塞客户端


< br>在客户端,使用


IBlockingConnection


可以简化套接字处理。与


NonBlockingconnection


不同的是,


BlockingConnection


不支持回调处理。



IBlockingConnectionbc = new BlockingConnection(host, port);



String req =


(req +



// read the whole logical part by waiting (blocking) until



// the required data have been received


String res = ringByDelimiter(



assert ((res));



4


、写非阻塞客户端



执行阻塞客户端的读方法,调用会在数据接收到或者超时事件发生后返回。


为了 避免这种情况,客户端需要定义处理


Handler


,当网络事 件发生后被调用。



IDataHandler



IDisconnectHandler




// defining the client handler (here as a anonymous inner class)


IDataHandlerclientHandler = new IDataHandler() {



publicbool eanonData(INonBlockingConnectionnbc)



throwsIOException,



BufferUnderflowException,



MaxReadSizeExceededException {









// read the whole logical part or throwing a BufferUnderflowException








String res = ringByDelimiter(








//...


return true;





}


};



// opening the connection


INonBlockingConnectionnbc = new NonBlockingConnection(host, port,


clientHandler);


(



// do something else. Receiving data causes that the client



// handler's onData method will be called (within a dedicated thread)


//...


5


、使用


blocking Connection


包装


non-blocking Connection


xSocket


在内部使用

< p>
INonblockingConnection


实现

IBlockingConnection.



也就


是说,


BlockingConnection


是带有阻塞行为的


read


方法的包装,于是


NonblockingConnection


可以随时变成

< br>BlockingConnection




INonBlockingConnectionnbc= ...



// wrapping an existing non-blocking connection by a BlockingConnection


IBlockingConnectionbc = new BlockingConnection(nbc);


t();


//...



6

、在服务端包装非阻塞


Connection


在多数情况 下,


NonblockingConnection


在服务端使 用,如果服务器端需要一



BlockingConnecti on



可以通过包装


NonBlock ingConnection


的方式创建。


包装


非阻塞


Connection


会导致赋给其的


Handler


在内部被移除。典型的是


onC onnect


方法会在服务端创建一个


BlockingCon nection




...


classConnectHandler implements IConnectHandler {


publicbooleanonConnec t(INonBlockingConnectionnbc) throws IOException {


IBlockingConnectionbc = new BlockingConnection(nbc);









//



return true;





}




...


7


、处理连接



通过实现


IConnectHandler


接口,

< p>
onConnect


回调用法会被调用。如果一个新


连接简历,


这个方法会被调用且仅被调用一次。


一般而言,< /p>


这个方法会被用来对


新连接进行安全检查,修改连接属性,准备资 源,设置回联或者发送欢迎信息。


在这个方法读取数据是不推荐的,因为数据不一定准备 好。



class Handler implements IDataHandler, IConnectHandler {



publicbooleanonConnect(INonBlockingConnection nbc) throws IOException {

















//... e.g. open resources


return true;






}


< /p>


publicbooleanonData(INonBlockingConnecti onnbc) throws IOException {










//...


return true;






}


}


8


、处理连接断开


< br>如果


Handler


实现了


ID isconnectHandler


接口,


onDisconn ect


会在连接终止的


时候调用


(不管 是当前进程终止连接或者远程终止)



尽管连接通过

< p>
onDisconnect


方法被当作参数传递,


但是任何读写操作都是不可以进行,


因为连接已经不存在。



三种关闭的情况:



A


、客户端主动关闭。这种情况下


onDisconnect

被直接调用



B


、连接损坏或者不 恰当的关闭,并且被


java


虚拟机检测到损坏连接。这种


情况下,


onDisconnect


会在检 测到损坏连接时调用。



C


、连接损坏 或者不恰当关闭,但是没有被


java


虚拟机检测到。这种情况 下


需要实现


IIdleTimeoutHandler



IConnectionTimeoutHandler


接口,因为


onDisconnect


不会被调用。



class Handler implements IDataHandler, IDisconnectHandler {



publicbooleanonDisconnect(INonBlockingConn ectionnbc) throws IOException {










//... e.g. closing open resources


return true;






}


< /p>


publicbooleanonData(INonBlockingConnecti onnbc) throws IOException


ByteBuffer[] data = teBufferByDelimiter(









// print out the received data





ByteBuffer[] copy = new ByteBuffer[];


for (inti = 0; i<; i++) {


copy[i] = data[i].duplicate();









}


n(ng(copy));









//...


return true;






}


}


在 连接断开的情况下,


IDataHandler


也被调用(在调 用


IDisconnectHandler


之前)


。与本地套接字读取一样,如果连接已经关闭,


INonblockingC onnection



available

方法返回


-1



进行读取,


会排除


ClosedChannelException



如果不处理会



xSoc ket


自动处理。



8


、异步连接



一般的创建阻塞和非阻塞连接都是同步的过程,


也就意味着在创建完成后立

< p>
即可以调用读写方法。不过,一些客户端的非阻塞连接在创建时包含了一个


waitForConnect


的参数,如果这个参数被设置为


false


,连接创建者不等待连接完


成建立就直接返回。下面 展示了如何异步创建连接。同样的,


Handler


对象需要< /p>


是想


IConnectionExceptionHandler


来处理连接异常。



class Handler implements IConnectHandler, IDataHandler,


IConnectExceptionHandler {



publicbooleanonConnect(INonBlockingConn ectionnbc) throws IOException {


(









//...


return true;



publicbooleanonConnectExcep tion(INonBlockingConnectionnbc,


IOExceptionioe) throws IOException {








//...


return true;





}



pu blicbooleanonData(INonBlockingConnectionnbc) throws IOException {








//...




return true;





}


}


Handler hdl = new Handler();



INonBlockingConnectionnbc = new


NonBlockingConnection(ame(host), port, hdl, false, 2000);



//...


// write operations are only valid after the connection has been established which


is indicated by the onConect() callback


如果在创建非阻塞方法返回后立即调用


write


方法,由于无法预测连接是否


建 立完成则会出现竞争条件。


onConnect


方法的调用标志 着连接的完成建立。



10


、处理超时


xSocket


支持连接超时和空闲超时。连接超时定义了连接的最长生命周期,< /p>


与流量无关,


连接会在超出连接事件后被关闭。

< br>空闲超时定义了在没有数据接收


时的最长空闲时间,


为了 防止没有响应的连接浪费资源,


一旦连接空闲时间超时


就会被关 闭。默认的的超时时间是一个最大值,大概是


24


天。



连接的超时事件可以被用户处理。通过实现


I IdleTimeoutHandler



IConnecti onTimeoutHandler


,对应的


onconnec tionTimeout



onIdleTimeout


方法


会被调用。如果这些方法返回


true< /p>


,表明这些事件已经被处理,连接就不会被想


Socket


关闭。如果返回


false



xSocket


则会关闭这些连接。



连接的空闲超时时间可以针对每一个连接调用


setConnectionti meoutsec()



setIdletimeoutSec ()


方法设定,同样的也调用这些方法来重设。例如超时在一个超


时回调方法中设定并且返回


true



那么这个超时事件就会表现的像从来没有发生


过。



服务端的默认超时行为可以通过服务器端的超时设置函数修改。



// the handler


class Handler implements IDataHandler, IIdleTimeoutHandler,


IConnectionTimeoutHandler {



publicbooleanonConnectionTimeout(INonBl ockingConnectionnbc) throws


IOException {


(


();



return true;



// prevent, that xSocket also closes the connection






}




pu blicbooleanonIdleTimeout(INonBlockingConnectionnbc ) throws IOException


{


(



eTimeoutMillis(30 * 1000); // resets the timeout counter


return true;



// prevent, that xSocket closes the connection






}




publicbooleanonData(INonBlo ckingConnectionnbc) throws IOException {










//...



return true;






}


}



// and the server


IServer server = new Server(8090, new Handler());


eTimeoutMillis(30 * 1000);





// set the default idle timeout for


server-side connections


();


11


、回调方法的同步



onConnect



onData


这样的回调方法会根据连接同步处理,也就是说对伊同


一个连接,如果


onConnect


不执行完成,那么用户也不会调用

< br>onData




class Handler implements IConnectHandler, IDataHandler {



publicbooleanonConnect(INon BlockingConnectionnbc) throws IOException {


(









//...








// DO NOT DO THIS!








// this causes that onData() will never be called because executing of









// callback methods is synchronized based on the connection


while (true) {


try {


(1000);












} catch (InterruptedException ignore) {



}


(









}








// You could define a TimerTask and run it within a Timer (thread)









// to implement the


return true;





}



pu blicbooleanonData(INonBlockingConnectionnbc) throws IOException {








String msg = ringByDelimiter(








//...




return true;





}


}




12


、定义连接作用域的

< p>
Handler


默认的


Handler


作用域是实例作用域(全局)


。也就是同一个


H andler


可以用


于每一个新进入的连接。

< br>一个


Handler


通过实现


I ConnectionScoped


接口来转变成


连接作用域的 。这个接口需要一个可以被用来为新连接创建专门


Handler


实例的


clone


方法。为了避免副作用,

< br>clone


方法需要实现成深度拷贝。



classSmtpHandler implements IDataHandler, IConnectionScoped {



privateinthandledMessages = 0;


privateSessionDatasessionData = new SessionData();



publicboolea nonData(INonBlockingConnectionnbc) throws IOException {







//...


return true;




}





// deep clone: all attributes beside primitives, immutable or





// global manager/service references have also to be cloned


public Object clone() throws CloneNotSupportedException {


SmtpHandler copy = (SmtpHandler) ();


nData = (SessionData) ();


return copy;




}


}


通过声明

Handler


为连接作用域,


在支持深度拷贝的情况下,


Handler


的变量


自动变成连接指 定的。


同时除了这种显式的往连接发送数据的方法之外,


隐式的


方法也是支持的。



13


、绑定会话相关的数据到连接


< /p>


一个可选的向连接分发会话数据的方法是直接附加数据。一般而言,这是推


荐的方法。一个连接支持附件特定连接的会话数据通过


setAttachme nt(object)



getAttachment()


方法。



classSmtpHandler implements IConnectHandler, IDataHandler {



publicbooleanonConnect(INonBlockingConnection nbc) throws IOException {


achment(new SessionData());


return true;





}



publicbooleanonData(INonBlo ckingConnectionnbc) throws IOException {


SessionDatasessionData = (SessionData) achment();







//...


return true;




}


}


14


、运行时替换


Handler < /p>


xSocket


支持在运行时替换


Han dler


,这可以在服务器端为所有新进入的连接


应用新的


Handler


。如果连接已经建立,可以调用

setHandler


方法来替换当前连


接的


Handler




classServerHandlerA implements IDataHandler {


publicbooleanonData(INon BlockingConnectionnbc) throws IOException {








String cmd = ringByDelimiter(


if ((


dler(new ServerHandlerB());








} else {


(








}



return true;





}


}


在服务器端


Handler


赋给了


server



这个


Handler


会赋值给每一个新进入的连


接,可以通过调用


setHandler


方法来替换。



classServerSideHandler implements IDataHandler {





@Resource


private Server server;





publicbooleanonData(INonBlockingConnection connection) throws IOException


{








String cmd = ringByDelimiter(


if ((


dler(new ServerHandlerB());


(


(









} else {


(








}



return true;





}


}


15


、示例:简单的基于长度的


Han dler


为了应用基于长度的通信方法,


连接的


mark-support


可以使用,


这种情况下,


客户端首先写一个空的长度属性,


在写完内容数据之后,


写指针会移回到长度属


性域来覆盖长度属性域。



IBlockingConnectionbc = new BlockingConnection(host, port);


oflush(false); // mark support requires deactivated autoflush!

-


-


-


-


-


-


-


-



本文更新与2021-02-15 14:26,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/655444.html

xsocket使用指南【官方文档翻译】的相关文章