Java NIO無(wú)法綁定指定IP和端口解決方案
在使用SNMP4J時(shí),我想指定創(chuàng)建的客戶(hù)端使用的本地IP和端口,因?yàn)樵赟ocket時(shí)這是可以的,但是發(fā)現(xiàn)無(wú)法實(shí)現(xiàn)
因?yàn)镾NMP4J底層的通信是使用NIO實(shí)現(xiàn)的,而NIO編程時(shí)貌似就不能顯示的指定
例如在SNMP4J的DefaultTcpTransportMapping類(lèi)里面,當(dāng)作為客戶(hù)端需要發(fā)送消息時(shí),程序首先判斷是否創(chuàng)建了這個(gè)客戶(hù)端,如果沒(méi)有在創(chuàng)建時(shí)看到這樣的代碼:
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中,客戶(hù)端是無(wú)法指定自己的IP和端口的!
那么有人在想為什么需要指定自己的IP和端口?具體需求我就不再說(shuō)了,在計(jì)算機(jī)上雖然只有一塊網(wǎng)卡,但是我們可以使用兼容的IP:
由于我的服務(wù)端程序以客戶(hù)端IP來(lái)判斷信息來(lái)源,現(xiàn)在我需要在我的電腦上做測(cè)試程序,需要同時(shí)邦定兩個(gè)IP地址進(jìn)行消息發(fā)送。
此時(shí)我就可以在高級(jí)設(shè)置里面設(shè)置兼容IP就可以,但是現(xiàn)在程序卻無(wú)法選擇。
在Socket里面可以這樣寫(xiě):
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 {// 創(chuàng)建非邦定式連接對(duì)象ServerSocket ss = new ServerSocket();// 需要邦定的本地IP和地址SocketAddress address = new InetSocketAddress('192.168.0.109', 2330);// 將連接對(duì)象邦定到地址ss.bind(address);System.out.println('服務(wù)已經(jīng)啟動(dòng)');while (true) {// 接收請(qǐng)求Socket socketClient = ss.accept();// 客戶(hù)端IPString ip = socketClient.getInetAddress().getHostAddress();// 客戶(hù)端端口int port = socketClient.getPort();System.out.println('服務(wù)端收到請(qǐng)求:' + ip + '/' + port);}}}
服務(wù)端很簡(jiǎn)單,你可以一行代碼搞定,也可以顯示的指定IP、端口,然后進(jìn)行顯示的服務(wù)連接操作:
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();// 需要邦定的本地IPInetAddress iaddThis = InetAddress.getByName('192.168.1.109');// 需要邦定的本地地址SocketAddress saddThis = new InetSocketAddress(iaddThis,2331);socket.bind(saddThis);// 連接的遠(yuǎn)程服務(wù)地址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);}}
注釋掉的內(nèi)容是一行搞定連接的方式。
經(jīng)過(guò)測(cè)試,如果想要修改所邦定的IP和顯示再次進(jìn)行連接操作,需要把設(shè)置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;}
否則會(huì)報(bào)錯(cuò):
Exception in thread 'main' java.nio.channels.IllegalBlockingModeExceptionat 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)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. html小技巧之td,div標(biāo)簽里內(nèi)容不換行2. HTML DOM setInterval和clearInterval方法案例詳解3. XML入門(mén)的常見(jiàn)問(wèn)題(一)4. CSS Hack大全-教你如何區(qū)分出IE6-IE10、FireFox、Chrome、Opera5. CSS hack用法案例詳解6. 詳解盒子端CSS動(dòng)畫(huà)性能提升7. msxml3.dll 錯(cuò)誤 800c0019 系統(tǒng)錯(cuò)誤:-2146697191解決方法8. 詳解瀏覽器的緩存機(jī)制9. 告別AJAX實(shí)現(xiàn)無(wú)刷新提交表單10. 讀大數(shù)據(jù)量的XML文件的讀取問(wèn)題
