手机端小强原创文章,java小强个人博客站点
当前位置: 首页 >> NET >> Java NIO 时不能邦定指定IP和端口

Java NIO 时不能邦定指定IP和端口

24180 NET | 2014-7-14

在使用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)

 

推荐您阅读更多有关于“ java 网络编程 nio 邦定端口 snmp snmp4j ”的文章

上一篇:通过Java HTTP连接将网络图片下载到本地 下一篇:Kaptcha 在Web页面生成验证码

猜你喜欢

发表评论:

个人资料
blogger

java小强
没有思考,人生的路会越走越难!

搜索
分类
最新微语
  • 今天同学问我,最近还在写代码吗?我想了想,这个问题怎么回答呢,我好像确实很长时间,虽然写了一些,但是主要内容已经不是写代码了。然后再想想,自己也7年多了,这么多年了,我收获了什么,我的目标到底是什么。眼看就奔三了,人生啊,开启感叹模式。

    2017-03-30 22:52

  • 也许大家都已经注意到了,今年的房价,好多地方都是翻了一番,跟着就是,各地房东开始变相涨租。今年之所以搬走,就是为此,这两天同学也是如此。很多房东只认钱,别谈感情,伤钱。而对于这个城市来说,你怎么定位自己,你真把自己当成她的一份子?你来此为何?将来何去何从?自己掂量清楚。

    2016-12-05 10:03

  • 为什么一直不写了呢?因为当爸爸了,没空了。今年的冬天,有些寒冷,除了这寒冬带来的不适,更有因乐视公司遇到危机,而带来的同事别离。送别同事,看着空旷的工位,心中有些悲凉。临近年关,此时此刻,该怎么做,似乎不再是脑子一热那么简单了。

    2016-11-24 11:28

  • 已经请假,加上国庆,要很长一段时间不在北京了。919加班,搞的现在有点心累,胸闷,身体不适。看来,我要好好休息一下了。这几天有些冷,2016的冬天,一步步来了,各位亲友,记得添衣加粗啊。

    2016-09-23 17:29

  • 现在是真的有秋天的感觉了,晚上也不热了,白天也凉快了。再来点风,那酸爽,就有一种想出去防风的冲动了。不过因为最近广州的事情压着,我也没办法,搞的特别累,以前是天天加班不想有自由,现在是因为有事情了,被限制了自由。加上公司的一些事情,感觉日子特别的无聊。

    2016-08-31 17:39

  • 更多»

最新文章
热门文章
随机文章