package concurrentTest; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; /** * UDP/IP阻塞模式 * */ public class UDPBIO { /** * 服务器端和客户端类似 * @param ipStr IP地址 * @param portNum 端口号 * */ public void udpListen(String ipStr, int portNum) { try { //若希望是全双工模式,则启动一个监听端口,承担服务器的职责 //若不能绑定到指定端口,则抛出SocketException DatagramSocket serverSocket = new DatagramSocket(portNum); InetAddress server = InetAddress.getByName(ipStr); byte[] buffer = new byte[65507]; DatagramPacket receivePacket = new DatagramPacket(buffer,buffer.length); DatagramSocket socket = new DatagramSocket(); DatagramPacket packet = new DatagramPacket(buffer,buffer.length,server,portNum); //阻塞发送packet到指定的服务器和端口 //网络IO异常,抛出IOExceprion //连不上IP和端口,抛出PortUnreachableException socket.send(packet); //阻塞并同步读取流信息,如接收到的信息流比packet长,则删除更长的信息 serverSocket.receive(receivePacket); } catch (SocketException e) { // 若不能绑定到指定端口 e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { // TODO Auto-generated method stub } }
============================================================================================================================================================================================================================================================================================================================================================================================================
package concurrentTest; import java.io.IOException; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.MulticastSocket; import java.net.SocketAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; /** * UDP/IP非阻塞模式 * */ public class UDPNIO { /** * 服务器端和客户端类似 * @param ipStr IP地址 * @param portNum 端口号 * */ public void udpListen(String ipStr, int portNum) { try { ByteBuffer buffer = ByteBuffer.allocate(1024); DatagramChannel reveiveChannel = DatagramChannel.open(); reveiveChannel.configureBlocking(false); DatagramSocket socket = reveiveChannel.socket(); socket.bind(new InetSocketAddress(portNum)); Selector selector = Selector.open(); reveiveChannel.register(selector, SelectionKey.OP_READ); //之后可采取和TCP/IP NIO中对selector遍历方式进行流信息的读取 DatagramChannel sendChannel = DatagramChannel.open(); sendChannel.configureBlocking(false); SocketAddress target = new InetSocketAddress(InetAddress.getLocalHost(), portNum); sendChannel.connect(target); //阻塞写入流,若发送缓冲区已满,返回0,此时可继续注册OP_WRITE事件 sendChannel.write(buffer); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 组播 * */ public void multicaseListen(String ipStr, int portNum) { try { InetAddress groupAddress = InetAddress.getByName(ipStr); MulticastSocket server = new MulticastSocket(portNum); //加入组播,若地址为非组播地址,抛出IOException //若不希望再发送数据到组播地址或者不希望再读取数据,可调用server.leaveGroup(组播地址) server.joinGroup(groupAddress); MulticastSocket client = new MulticastSocket(); client.joinGroup(groupAddress); // } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // 若地址为非组播地址 e.printStackTrace(); } } public static void main(String[] args) { // TODO Auto-generated method stub } }