我正在使用java NIO制作一个示例p2p网络,并且遇到一些麻烦。
这是方案
1个节点同时具有客户端和服务器功能。我使用NIO作为服务器功能,使用普通的socketchannel作为客户端
我在每个节点的2个独立线程中运行NIO服务器功能和客户端功能。 NIO服务器使用ServerSocketChannel和选择器
NIO客户端将创建一个SocketChannel并连接到要连接的节点的ServerSocketChannel。
我的问题是:目前,发件人和收件人使用分开的端口。如何将它们合并为仅使用1来发送和接收?
这是接收器的代码
public Receiver(short port) {
try {
ServerSocketChannel serverSocketChannel = ServerSocketChannel
.open();
serverSocketChannel.socket().setReuseAddress(true);
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(port));
this.channel = serverSocketChannel;
Selector selector = Selector.open();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_ACCEPT);
p2pProtocol = new Protocol(port);
while (true) {
int readyChannels = selector.select();
if (readyChannels == 0) {
// Accept channel is busy
continue;
}
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) {
// a connection request from other node
acceptKey(selector, key);
} else if (key.isConnectable()) {
// a connection was established with a remote server.
Log.writeLog("Connectable");
} else if (key.isReadable()) {
// a channel is ready for reading
receive(key);
} else if (key.isWritable()) {
// a channel is ready for writing
write(key);
}
keyIterator.remove();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这是发件人:
public Sender(InetAddress address, short remotePort, short serverPort) {
this.listeningPort = serverPort;
// Create socket connection
try {
socket = new Socket(address, remotePort);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
active = true;
} catch (IOException e) {
e.printStackTrace();
Log.writeLog("No I/O");
}
}
public boolean getStatus()
{
return active;
}
public Message sendMessage(MsgType type) {
Message m = MessageFactory.craftRequestMessage(type,
listeningPort, false);
try {
byte[] send = Conversion.serializeMessageToBytes(m).array();
out.flush();
out.write(send);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.writeLog(e.getMessage());
}
return m;
}