`
cuisuqiang
  • 浏览: 3954178 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
3feb66c0-2fb6-35ff-968a-5f5ec10ada43
Java研发技术指南
浏览量:3665173
社区版块
存档分类
最新评论

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

阅读更多

在使用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了解的人指点一下。

 

自建博客地址:http://www.javacui.com/ ,内容与ITEYE同步!

1
2
分享到:
评论
2 楼 cuisuqiang 2013-03-04  
shenliuyang 写道
                SocketChannel channel = SocketChannel.open();
Socket socket = channel.socket();
socket.bind(new InetSocketAddress("192.168.1.100", 999));
socket.connect(new InetSocketAddress("www.baidu.com", 80));
System.out.println(socket.getLocalAddress());
System.out.println(socket.getLocalPort());
channel.close();
你是想要这样的结果吗

谢谢提醒:
经过测试,如果想要修改所邦定的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)
1 楼 shenliuyang 2013-03-04  
                SocketChannel channel = SocketChannel.open();
Socket socket = channel.socket();
socket.bind(new InetSocketAddress("192.168.1.100", 999));
socket.connect(new InetSocketAddress("www.baidu.com", 80));
System.out.println(socket.getLocalAddress());
System.out.println(socket.getLocalPort());
channel.close();
你是想要这样的结果吗

相关推荐

    Java NIO Socket基本

    1. **ServerSocketChannel**:用于监听客户端连接,通过调用`ServerSocketChannel.open()`创建,然后绑定到指定的IP和端口,并调用`accept()`方法接收客户端连接。 2. **SocketChannel**:代表客户端与服务器之间的...

    Java 端口映射

    在Java中实现端口映射,主要可以利用Socket编程和NIO(非阻塞I/O)框架。以下是一些关键知识点: 1. **Socket编程**: Java的`java.net.Socket`和`java.net.ServerSocket`类是进行TCP/IP通信的基础。通过创建...

    java 端口扫描源代码

    - **异常处理**:捕获`ConnectException`或其他相关异常,作为端口不可达的标志。 - **超时设置**:为了避免因网络延迟导致的长时间等待,源代码可能会设置Socket连接超时,如`socket.setSoTimeout(timeout)`。 -...

    java BIO NIO AIO

    BIO 的工作机制是基于 Client/Server 模型的,服务器端负责绑定 IP 地址,启动监听端口;客户端负责发起连接操作。连接成功后,双方通过网络套接字(Socket)进行通信。在 BIO 模式下,客户端和服务端是完全同步的,...

    JAVANIO在Socket通讯中的应用

    3. **绑定地址**:将ServerSocketChannel绑定到特定的IP地址和端口号。 ```java serverChannel.socket().bind(new InetSocketAddress(port)); ``` 4. **注册Selector**:将ServerSocketChannel注册到Selector...

    java基于nio的socket通信.rar

    Java NIO(New IO)是Java 1.4版本引入的一个新特性,它为Java提供了非阻塞I/O操作的能力,极大地提升了Java在处理网络通信和文件读写时的性能。Socket通信是网络编程的基本元素,它允许两台计算机通过TCP/IP协议...

    Java NIO 聊天室 JSwing

    //这里和服务端的方法不一样,查看api注释可以知道,当至少一个通道被选中时, //selector的wakeup方法被调用,方法返回,而对于客户端来说,通道一直是被选中的 selector.select(); // 获得selector中选中的...

    NIO实现telnet

    1. **创建ServerSocketChannel并绑定到指定端口**:服务器首先创建一个ServerSocketChannel,并将其绑定到特定IP地址和端口号上,以等待客户端连接。 2. **注册选择器**:将ServerSocketChannel注册到选择器上,...

    NIO实现客户端之间通信

    - 创建SocketChannel,连接到服务器端的指定IP和端口。 - 同样,客户端也需要注册选择器,监听read和write事件,以便从服务器接收消息并发送自己的消息。 - 当选择器通知read事件时,读取服务器发送的数据;当...

    NIOServer

    1. **服务器端套接字(ServerSocketChannel)**:服务器首先会创建一个ServerSocketChannel,并将其绑定到特定的IP地址和端口号上,等待客户端的连接请求。 2. **选择器(Selector)注册**:然后,服务器会创建一个...

    【IT十八掌徐培成】Java基础第27天-02.NIO-ServerSocketChannel-SocketChannel.zip

    通过调用`ServerSocketChannel.open()`方法可以创建一个ServerSocketChannel对象,然后通过`bind()`方法绑定到指定的IP和端口上。当有客户端连接请求时,`accept()`方法会返回一个新的SocketChannel,用于处理客户端...

    android nio程序

    在Android平台上,`java.nio`(New Input/Output)库为开发者提供了高效的数据传输和缓冲区操作能力。这个库在Java SE中引入,也被Android完全支持。本篇将深入探讨`android nio`程序,主要关注`NioServer`和`Nio...

    Java-NIO之Selector.doc

    对于SocketChannel,服务端需要绑定到特定的IP和端口,而客户端则需要连接到服务端的地址。 3. **注册事件**: 通过调用`channel.register(selector, interestOps)`,你可以将通道注册到Selector,并指定感兴趣的...

    Java TCP-IP Socket编程-卡尔弗特.pdf

    客户端则通过Socket类建立到服务器的连接,并指定服务器的IP地址和端口号。一旦连接建立,双方可以通过输入/输出流进行双向通信。 在Java中,使用ServerSocket类的`bind()`方法绑定到特定端口,`accept()`方法等待...

    java TCP/IP socket 编程(原书第2版)pdf+源码

    在"Chapter2"中,可能会详细讲解如何创建并使用ServerSocket和Socket,包括设置端口号、绑定IP地址以及处理多个并发连接等。此外,还会涉及异常处理,确保在出现问题时能优雅地关闭连接。 "Chapter3"可能涵盖输入...

    java udp socket 网络编程

    - 使用`bind()`方法将DatagramSocket绑定到特定IP地址和端口,这样就能接收该端口上的数据报。 2. **发送数据报**: - 数据报通常由字节数组构建,可以使用`DatagramPacket`的构造函数将其包装起来,指定目标IP和...

    java HttpServer源码工程

    这个工程的核心在于理解如何使用Java NIO(非阻塞I/O)和Java网络编程来构建一个高效的服务器。下面我们将详细探讨Java HttpServer的实现原理、关键组件以及其在实际应用中的价值。 一、Java NIO基础 Java NIO(New...

    nio异步长连接服务端与客户端

    - **ServerSocketChannel的绑定与监听**:通过调用bind()方法绑定服务器的IP和端口,然后调用listen()方法开始监听连接请求。 - **Selector的注册与选择**:服务端创建Selector实例,将ServerSocketChannel注册到...

    Java+TCP/IP+Socket编程++原书第2版

    7. **NIO(非阻塞I/O)**:Java的NIO库提供了更高效的数据传输方式,特别是在处理大量并发连接时。Selector和Channel是NIO的关键组件,它们允许服务器以非阻塞的方式监控多个Socket连接。 8. **套接字选项**:...

Global site tag (gtag.js) - Google Analytics