首页 > 编程 > Java > 正文

Java Socket编程实例(五)- NIO UDP实践

2019-11-26 14:11:28
字体:
来源:转载
供稿:网友

一、回传协议接口和UDP方式实现:

1.接口:

import java.nio.channels.SelectionKey; import java.io.IOException;  public interface EchoProtocol {  void handleAccept(SelectionKey key) throws IOException;  void handleRead(SelectionKey key) throws IOException;  void handleWrite(SelectionKey key) throws IOException; } 

2.实现:

import java.net.SocketAddress; import java.nio.channels.*; import java.nio.ByteBuffer; import java.io.IOException;  public class UDPEchoSelectorProtocol implements <span style="font-size: 1em; line-height: 1.5;">EchoProtocol </span><span style="font-size: 1em; line-height: 1.5;">{</span>   private static final int ECHOMAX = 255; // Maximum size of echo datagram    static class ClientRecord {     public SocketAddress clientAddress;     public ByteBuffer buffer = ByteBuffer.allocate(ECHOMAX);   }    public void handleAccept(SelectionKey key) throws IOException {        }    public void handleRead(SelectionKey key) throws IOException {     DatagramChannel channel = (DatagramChannel) key.channel();     ClientRecord clntRec = (ClientRecord) key.attachment();     clntRec.buffer.clear(); // Prepare buffer for receiving     clntRec.clientAddress = channel.receive(clntRec.buffer);     if (clntRec.clientAddress != null) { // Did we receive something?       // Register write with the selector       key.interestOps(SelectionKey.OP_WRITE);     }   }    public void handleWrite(SelectionKey key) throws IOException {     DatagramChannel channel = (DatagramChannel) key.channel();     ClientRecord clntRec = (ClientRecord) key.attachment();     clntRec.buffer.flip(); // Prepare buffer for sending     int bytesSent = channel.send(clntRec.buffer, clntRec.clientAddress);     if (bytesSent != 0) { // Buffer completely written?       // No longer interested in writes       key.interestOps(SelectionKey.OP_READ);     }   }  }

二、NIO UDP客户端:

import java.net.InetSocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel;  public class UDPEchoClientNonblocking {    private static final int TIMEOUT = 3000; // Resend timeout (milliseconds)   private static final int MAXTRIES = 255; // Maximum retransmissions      public static void main(String args[]) throws Exception {     // Convert input String to bytes using the default charset     byte[] bytesToSend = "0123456789abcdefghijklmnopqrstuvwxyz".getBytes();      // Create channel and set to nonblocking     DatagramChannel datagramChannel = DatagramChannel.open();     datagramChannel.configureBlocking(false);     datagramChannel.socket().setSoTimeout(TIMEOUT);          ByteBuffer writeBuf = ByteBuffer.wrap(bytesToSend);     ByteBuffer readBuf = ByteBuffer.allocate(MAXTRIES);          datagramChannel = datagramChannel.connect(new InetSocketAddress("127.0.0.1", 5500));      int totalBytesRcvd = 0; // Total bytes received so far     int bytesRcvd; // Bytes received in last read     while (totalBytesRcvd < bytesToSend.length) {       if (writeBuf.hasRemaining()) {         datagramChannel.write(writeBuf);       }       if ((bytesRcvd = datagramChannel.read(readBuf)) == -1) {         throw new SocketException("Connection closed prematurely");       }       totalBytesRcvd += bytesRcvd;       System.out.print("."); // Do something else     }      System.out.println("Received: " + new String(readBuf.array(), 0, totalBytesRcvd));     datagramChannel.close();   } }

三、NIO UDP服务端:

import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.*; import java.util.Iterator;  public class UDPEchoServerSelector {    private static final int TIMEOUT = 3000; // Wait timeout (milliseconds)    public static void main(String[] args) throws IOException {     // Create a selector to multiplex client connections.     Selector selector = Selector.open();      DatagramChannel channel = DatagramChannel.open();     channel.configureBlocking(false);     channel.socket().bind(new InetSocketAddress(5500));     channel.register(selector, SelectionKey.OP_READ, new UDPEchoSelectorProtocol.ClientRecord());      UDPEchoSelectorProtocol echoSelectorProtocol = new UDPEchoSelectorProtocol();     while (true) { // Run forever, receiving and echoing datagrams       // Wait for task or until timeout expires       if (selector.select(TIMEOUT) == 0) {         System.out.print(".");         continue;       }        // Get iterator on set of keys with I/O to process       Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();       while (keyIter.hasNext()) {         SelectionKey key = keyIter.next(); // Key is bit mask          // Client socket channel has pending data?         if (key.isReadable())           echoSelectorProtocol.handleRead(key);          // Client socket channel is available for writing and         // key is valid (i.e., channel not closed).         if (key.isValid() && key.isWritable())           echoSelectorProtocol.handleWrite(key);          keyIter.remove();       }     }   }  }

以上就是本文的全部内容,查看更多Java的语法,大家可以关注:《Thinking in Java 中文手册》、《JDK 1.7 参考手册官方英文版》、《JDK 1.6 API java 中文参考手册》、《JDK 1.5 API java 中文参考手册》,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表