Java Socket编程实例(五)- NIO UDP实践
一、回传协议接口和UDP方式实现:
1.接口:
importjava.nio.channels.SelectionKey; importjava.io.IOException; publicinterfaceEchoProtocol{ voidhandleAccept(SelectionKeykey)throwsIOException; voidhandleRead(SelectionKeykey)throwsIOException; voidhandleWrite(SelectionKeykey)throwsIOException; }
2.实现:
importjava.net.SocketAddress; importjava.nio.channels.*; importjava.nio.ByteBuffer; importjava.io.IOException; publicclassUDPEchoSelectorProtocolimplements<spanstyle="font-size:1em;line-height:1.5;">EchoProtocol</span><spanstyle="font-size:1em;line-height:1.5;">{</span> privatestaticfinalintECHOMAX=255;//Maximumsizeofechodatagram staticclassClientRecord{ publicSocketAddressclientAddress; publicByteBufferbuffer=ByteBuffer.allocate(ECHOMAX); } publicvoidhandleAccept(SelectionKeykey)throwsIOException{ } publicvoidhandleRead(SelectionKeykey)throwsIOException{ DatagramChannelchannel=(DatagramChannel)key.channel(); ClientRecordclntRec=(ClientRecord)key.attachment(); clntRec.buffer.clear();//Preparebufferforreceiving clntRec.clientAddress=channel.receive(clntRec.buffer); if(clntRec.clientAddress!=null){//Didwereceivesomething? //Registerwritewiththeselector key.interestOps(SelectionKey.OP_WRITE); } } publicvoidhandleWrite(SelectionKeykey)throwsIOException{ DatagramChannelchannel=(DatagramChannel)key.channel(); ClientRecordclntRec=(ClientRecord)key.attachment(); clntRec.buffer.flip();//Preparebufferforsending intbytesSent=channel.send(clntRec.buffer,clntRec.clientAddress); if(bytesSent!=0){//Buffercompletelywritten? //Nolongerinterestedinwrites key.interestOps(SelectionKey.OP_READ); } } }
二、NIOUDP客户端:
importjava.net.InetSocketAddress; importjava.net.SocketException; importjava.nio.ByteBuffer; importjava.nio.channels.DatagramChannel; publicclassUDPEchoClientNonblocking{ privatestaticfinalintTIMEOUT=3000;//Resendtimeout(milliseconds) privatestaticfinalintMAXTRIES=255;//Maximumretransmissions publicstaticvoidmain(Stringargs[])throwsException{ //ConvertinputStringtobytesusingthedefaultcharset byte[]bytesToSend="0123456789abcdefghijklmnopqrstuvwxyz".getBytes(); //Createchannelandsettononblocking DatagramChanneldatagramChannel=DatagramChannel.open(); datagramChannel.configureBlocking(false); datagramChannel.socket().setSoTimeout(TIMEOUT); ByteBufferwriteBuf=ByteBuffer.wrap(bytesToSend); ByteBufferreadBuf=ByteBuffer.allocate(MAXTRIES); datagramChannel=datagramChannel.connect(newInetSocketAddress("127.0.0.1",5500)); inttotalBytesRcvd=0;//Totalbytesreceivedsofar intbytesRcvd;//Bytesreceivedinlastread while(totalBytesRcvd<bytesToSend.length){ if(writeBuf.hasRemaining()){ datagramChannel.write(writeBuf); } if((bytesRcvd=datagramChannel.read(readBuf))==-1){ thrownewSocketException("Connectionclosedprematurely"); } totalBytesRcvd+=bytesRcvd; System.out.print(".");//Dosomethingelse } System.out.println("Received:"+newString(readBuf.array(),0,totalBytesRcvd)); datagramChannel.close(); } }
三、NIOUDP服务端:
importjava.io.IOException; importjava.net.InetSocketAddress; importjava.nio.channels.*; importjava.util.Iterator; publicclassUDPEchoServerSelector{ privatestaticfinalintTIMEOUT=3000;//Waittimeout(milliseconds) publicstaticvoidmain(String[]args)throwsIOException{ //Createaselectortomultiplexclientconnections. Selectorselector=Selector.open(); DatagramChannelchannel=DatagramChannel.open(); channel.configureBlocking(false); channel.socket().bind(newInetSocketAddress(5500)); channel.register(selector,SelectionKey.OP_READ,newUDPEchoSelectorProtocol.ClientRecord()); UDPEchoSelectorProtocolechoSelectorProtocol=newUDPEchoSelectorProtocol(); while(true){//Runforever,receivingandechoingdatagrams //Waitfortaskoruntiltimeoutexpires if(selector.select(TIMEOUT)==0){ System.out.print("."); continue; } //GetiteratoronsetofkeyswithI/Otoprocess Iterator<SelectionKey>keyIter=selector.selectedKeys().iterator(); while(keyIter.hasNext()){ SelectionKeykey=keyIter.next();//Keyisbitmask //Clientsocketchannelhaspendingdata? if(key.isReadable()) echoSelectorProtocol.handleRead(key); //Clientsocketchannelisavailableforwritingand //keyisvalid(i.e.,channelnotclosed). if(key.isValid()&&key.isWritable()) echoSelectorProtocol.handleWrite(key); keyIter.remove(); } } } }
以上就是本文的全部内容,查看更多Java的语法,大家可以关注:《ThinkinginJava中文手册》、《JDK1.7参考手册官方英文版》、《JDK1.6APIjava中文参考手册》、《JDK1.5APIjava中文参考手册》,也希望大家多多支持毛票票。