- 2024-02-10 12:27:52
- 9054 热度
- 0 评论
在使用SNMP4J时,我想指定创建的客户端使用的本地IP和端口,因为在Socket时这是可以的,但是发现无法实现
因为SNMP4J底层的通信是使用NIO实现的,而NIO编程时貌似就不能显示的指定
例如在SNMP4J的DefaultTcpTransportMapping类里面,当作为客户端需要发送消息时,程序首先判断是否创建了这个客户端,如果没有在创建时看到这样的代码:
SocketChannel sc = null; try { sc = SocketChannel.open(); sc.configureBlocking(false); sc.connect(new InetSocketAddress(((TcpAddress) address).getInetAddress(),((TcpAddress) address).getPort())); s = sc.socket(); entry = new SocketEntry((TcpAddress) address, s); entry.addMessage(message); sockets.put(address, entry); synchronized (pending) { pending.add(entry); } selector.wakeup(); logger.debug("Trying to connect to " + address); } catch (IOException iox) { logger.error(iox); throw iox; }
即使在SocketChannel中,他的Socket变量定义也是不能修改的:
/** * Retrieves a socket associated with this channel. * * <p> The returned object will not declare any public methods that are not * declared in the {@link java.net.Socket} class. </p> * * @return A socket associated with this channel */ public abstract Socket socket();
所以我直接判定Java NIO中,客户端是无法指定自己的IP和端口的!
那么有人在想为什么需要指定自己的IP和端口?具体需求我就不再说了,在计算机上虽然只有一块网卡,但是我们可以使用兼容的IP:
由于我的服务端程序以客户端IP来判断信息来源,现在我需要在我的电脑上做测试程序,需要同时邦定两个IP地址进行消息发送。
此时我就可以在高级设置里面设置兼容IP就可以,但是现在程序却无法选择。
在Socket里面可以这样写:
package com.xidian.nms.socket; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; public class SocketServer { public static void main(String[] args) throws Exception { // 创建非邦定式连接对象 ServerSocket ss = new ServerSocket(); // 需要邦定的本地IP和地址 SocketAddress address = new InetSocketAddress("192.168.0.109", 2330); // 将连接对象邦定到地址 ss.bind(address); System.out.println("服务已经启动"); while (true) { // 接收请求 Socket socketClient = ss.accept(); // 客户端IP String ip = socketClient.getInetAddress().getHostAddress(); // 客户端端口 int port = socketClient.getPort(); System.out.println("服务端收到请求:" + ip + "/" + port); } } }
服务端很简单,你可以一行代码搞定,也可以显示的指定IP、端口,然后进行显示的服务连接操作:
package com.xidian.nms.socket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; public class SocketClient { public static void main(String[] args) throws Exception{ Socket socket = new Socket(); // 需要邦定的本地IP InetAddress iaddThis = InetAddress.getByName("192.168.1.109"); // 需要邦定的本地地址 SocketAddress saddThis = new InetSocketAddress(iaddThis,2331); socket.bind(saddThis); // 连接的远程服务地址 InetAddress iaddRe = InetAddress.getByName("192.168.0.109"); SocketAddress saddRe = new InetSocketAddress(iaddRe,2330); // 显示连接 socket.connect(saddRe); // Socket socket = new Socket("192.168.0.109", 2330); } }
注释掉的内容是一行搞定连接的方式。
当然这是我发现的一个问题,不知道如何解决,希望对NIO了解的人指点一下。
后有高人提示,解决该问题,且经过测试,如果想要修改所邦定的IP和显示再次进行连接操作,需要把设置NIO同步的代码放到后面:
try { sc = SocketChannel.open(); s = sc.socket(); s.bind(new InetSocketAddress("192.168.0.109", 999)); s.connect(new InetSocketAddress(((TcpAddress) address).getInetAddress(),((TcpAddress) address).getPort())); sc.configureBlocking(false); entry = new SocketEntry((TcpAddress) address, s); entry.addMessage(message); sockets.put(address, entry); synchronized (pending) { pending.add(entry); } selector.wakeup(); logger.debug("Trying to connect to " + address); } catch (IOException iox) { logger.error(iox); throw iox; }
否则会报错:
Exception in thread "main" java.nio.channels.IllegalBlockingModeException at sun.nio.ch.SocketAdaptor.connect(SocketAdaptor.java:76) at sun.nio.ch.SocketAdaptor.connect(SocketAdaptor.java:65) at org.snmp4j.transport.DefaultTcpTransportMapping$ServerThread.sendMessage(DefaultTcpTransportMapping.java:503) at org.snmp4j.transport.DefaultTcpTransportMapping.sendMessage(DefaultTcpTransportMapping.java:183) at org.snmp4j.MessageDispatcherImpl.sendMessage(MessageDispatcherImpl.java:214) at org.snmp4j.MessageDispatcherImpl.sendPdu(MessageDispatcherImpl.java:475) at org.snmp4j.Snmp.sendMessage(Snmp.java:1110) at org.snmp4j.Snmp.send(Snmp.java:914) at org.snmp4j.Snmp.send(Snmp.java:894) at org.snmp4j.Snmp.send(Snmp.java:859) at com.xidian.nms.snmp.Snmp4jGet.sendPDU(Snmp4jGet.java:59) at com.xidian.nms.snmp.Snmp4jGet.main(Snmp4jGet.java:38)
0 评论
留下评论
热门标签
- Spring(403)
- Boot(208)
- Spring Boot(187)
- Java(82)
- Cloud(82)
- Spring Cloud(82)
- Security(60)
- Spring Security(54)
- Boot2(51)
- Spring Boot2(51)
- Redis(31)
- SQL(29)
- Mysql(25)
- IDE(24)
- Dalston(24)
- MVC(22)
- JDBC(22)
- IDEA(22)
- mongoDB(22)
- Web(21)
- CLI(20)
- SpringMVC(19)
- Alibaba(19)
- SpringBoot(17)
- Docker(17)
- Git(16)
- Eclipse(16)
- Vue(16)
- ORA(15)
- JPA(15)
- Apache(15)
- Mybatis(14)
- Oracle(14)
- jdk(14)
- Tomcat(14)
- Linux(14)
- HTTP(14)
- XML(13)
- JdbcTemplate(13)
- OAuth(13)
- Nacos(13)
- Pro(13)
- Data(12)
- JSON(12)
- OAuth2(12)
- stream(11)
- int(11)
- Myeclipse(11)
- Bug(10)
- not(10)
- ast(9)
- maven(9)
- Map(9)
- Hystrix(9)
- Swagger(8)
- APP(8)
- Bit(8)
- API(8)
- session(8)
- Window(8)
- HTML(7)
- Github(7)
- JavaMail(7)
- Cache(7)
- File(7)
- IntelliJ(7)
- mail(7)
- windows(7)
- too(7)
- RabbitMQ(6)
- and(6)
- star(6)
- Excel(6)
- Log4J(6)
- pushlet(6)
- apt(6)
- read(6)
- Freemarker(6)
- WebFlux(6)
- JSP(6)
- Bean(6)
- error(6)
- nginx(6)
- Server(6)
- jar(6)
- ueditor(6)
- ehcache(6)
- UDP(6)
- JWT(5)
- rdquo(5)
- PHP(5)
- Struts(5)
- string(5)
- Syntaxhighlighter(5)
- script(5)
- Tool(5)
- Controller(5)
- swagger2(5)
- ldquo(5)
- input(5)