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中文参考手册》,也希望大家多多支持毛票票。