package example; /** * 端口转发 */ //import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.HashMap; import java.util.Iterator; public class myServer { public static final int PORTClient = 8085; public static final int PORTDevice = 8081; protected static HashMap<String,SelectionKey> map = new HashMap<String, SelectionKey>(); //定义选择器 protected Selector selector; protected Selector selector_device; int clientCount; int deviceCount; public myServer() throws Exception { //外部访问的socket和selector selector = Selector.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(PORTClient)); // port serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// register p("Server localhost:" + PORTClient + " started. waiting for clients. "); //内部设备端口 selector_device=Selector.open(); ServerSocketChannel serverSocketChannelDevice = ServerSocketChannel.open(); serverSocketChannelDevice.socket().bind(new InetSocketAddress(PORTDevice)); serverSocketChannelDevice.configureBlocking(false); serverSocketChannelDevice.register(selector_device, SelectionKey.OP_ACCEPT); p("Server localhost:" + PORTDevice + " started. waiting for Device. "); Client client=new Client(); Device device=new Device(); device.run(); while (true) { client.run(); } } class Client implements Runnable{ @Override public void run() { // TODO Auto-generated method stub try { // selector 线程。select() 会阻塞,直到有客户端连接,或者有消息读入 selector.select(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); // hashmap.put(, selectionKey); iterator.remove(); // 删除此消息 // 并在当前线程内处理。(为了高效,一般会在另一个线程中处理此消息,例如使用线程池等) try { handleSelectionKey(selectionKey); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void start() { // TODO Auto-generated method stub } } class Device implements Runnable { @Override public void run() { // TODO Auto-generated method stub // try { selector_device.select(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Iterator<SelectionKey> iteratorDevice = selector_device.selectedKeys().iterator(); while (iteratorDevice.hasNext()) { SelectionKey selectionKeyDevice = iteratorDevice.next(); System.out.println(selectionKeyDevice); // hashmap.put(, selectionKey); iteratorDevice.remove(); // 删除此消息 // 并在当前线程内处理。(为了高效,一般会在另一个线程中处理此消息,例如使用线程池等) try { handleDevice(selectionKeyDevice); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void start() { // TODO Auto-generated method stub } } //内部设备连接 private void handleDevice(SelectionKey selectionKeyDevice) throws IOException { // TODO Auto-generated method stub if (selectionKeyDevice.isAcceptable()) { // 有客户端进来 deviceCount++; System.out.println(deviceCount); ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKeyDevice.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); Socket socket = socketChannel.socket(); // 立即注册一个 OP_READ 的SelectionKey, 接收客户端的消息 SelectionKey key = socketChannel.register(selector_device, SelectionKey.OP_READ); System.out.println(key); String str=socket.getRemoteSocketAddress().toString(); String [] strs = str.split("[:]"); //做内部设备的访问map map.put(strs[0], key); System.out.println(map.get(socket.getRemoteSocketAddress())); System.out.println(socket.getInetAddress().getHostAddress()); key.attach("第 " + deviceCount + " 个内部设备 [" + socket.getRemoteSocketAddress() + "]: "); p(key.p_w_upload() + "\t[connected] ========================================="); } else if (selectionKeyDevice.isReadable()) { // 有消息进来 ByteBuffer byteBufferD = ByteBuffer.allocate(100); SocketChannel socketChannel = (SocketChannel) selectionKeyDevice.channel(); try { int len = socketChannel.read(byteBufferD); if (len > 0) { byteBufferD.flip();//flip()方法用来将缓冲区准备为数据传出状态,这通过将limit设置为position的当前值,再 将position的值设为0来实现 socketChannel.write(byteBufferD); //socketChannelDevice.write(byteBuffer); } else { // 输入结束,关闭 socketChannel p(selectionKeyDevice.p_w_upload() + "read finished. close socketChannel. "); socketChannel.close(); } } catch (Exception e) { // 如果read抛出异常,表示连接异常中断,需要关闭 socketChannel e.printStackTrace(); p(selectionKeyDevice.p_w_upload() + "socket closed? "); socketChannel.close(); } } else if (selectionKeyDevice.isWritable()) { p(selectionKeyDevice.p_w_upload() + "TODO: isWritable() ???????????????????????????? "); } else if (selectionKeyDevice.isConnectable()) { p(selectionKeyDevice.p_w_upload() + "TODO: isConnectable() ????????????????????????? "); } else { p(selectionKeyDevice.p_w_upload() + "TODO: else. "); } } //外部用户访问 public void handleSelectionKey(SelectionKey selectionKey) throws Exception { if (selectionKey.isAcceptable()) { // 有客户端进来 clientCount++; ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); Socket socket = socketChannel.socket(); System.out.println(serverSocketChannel.socket().getLocalSocketAddress()); // 立即注册一个 OP_READ 的SelectionKey, 接收客户端的消息 SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ); key.attach("第 " + clientCount + " 个客户端 [" + socket.getRemoteSocketAddress() + "]: "); p(key.p_w_upload() + "\t[connected] ========================================="); } else if (selectionKey.isReadable()) { // 有消息进来 ByteBuffer byteBuffer = ByteBuffer.allocate(100); ByteBuffer byteBufferDD= ByteBuffer.allocate(100); SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); SocketChannel socketChannelDevice=(SocketChannel)map.get("/192.168.1.102").channel(); System.out.println(map.get("/192.168.1.102")); //System.out.println(socketChannelDevice.socket().getPort()); try { //向设备发指令 int instruction = socketChannel.read(byteBuffer); int data=socketChannelDevice.read(byteBufferDD); if (instruction > 0) { byteBuffer.flip();//flip()方法用来将缓冲区准备为数据传出状态,这通过将limit设置为position的当前值,再 将position的值设为0来实现 //socketChannel.write(byteBuffer); socketChannelDevice.write(byteBuffer); } //向外部连接传数据 else if (data > 0) { byteBuffer.flip(); socketChannel.write(byteBuffer); } else { // 输入结束,关闭 socketChannel p(selectionKey.p_w_upload() + "read finished. close socketChannel. "); socketChannel.close(); } } catch (Exception e) { // 如果read抛出异常,表示连接异常中断,需要关闭 socketChannel e.printStackTrace(); p(selectionKey.p_w_upload() + "socket closed? "); socketChannel.close(); } } else if (selectionKey.isWritable()) { p(selectionKey.p_w_upload() + "TODO: isWritable() ???????????????????????????? "); } else if (selectionKey.isConnectable()) { p(selectionKey.p_w_upload() + "TODO: isConnectable() ????????????????????????? "); } else { p(selectionKey.p_w_upload() + "TODO: else. "); } } public static void p(Object object) { System.out.println(object); } public static void main(String[] args) throws Exception { new myServer(); } }
NIO实现端口转发
原创
©著作权归作者所有:来自51CTO博客作者wutongkege的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:ubuntu 获得root权限
下一篇:SOCKET读取音频数据存入文件
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Linux或Windows上实现端口映射
通常服务器会有许多块网卡,因此也可能会连接到不同的网络,在隔离的网络中,某些服务可能会需要进行通信,此时服务器经过配置就可以承担起了转发数据包的功能。
内网 外网 端口映射 Linux或Windows上实现端口映射 RHCE -
Java NIO - IO多路复用详解
本文主要对IO多路复用,Ractor模型以及Java NIO对其的支持。
Java IO/NIO/AIO -
Nginx 实现端口转发
https://www.cnblogs.com/zhaoyingjie/p/7248678.html Nginx 实现端口转发 什么是端口转发 当我们在服务器上搭建
nginx 端口转发 请求转发 配置文件 服务器 -
[转]xshell实现端口转发
跳板机:10.127.10.1 目标机:10.127.4.25:808
xshell javascript 远程服务器 数据 端口转发