我有一个java.nio.channels.ServerSocketChannel
我初始化如下:
while(true)
{
ServerSocketChannel channel = ServerSocketChannel.open();
InetSocketAddress serverSocket = new InetSocketAddress(host,port);
channel.bind(serverSocket);
SocketChannel ch = channel.accept();
// Later on when I have read off data from a client, I want to shut this
// connection down and restart listening.
channel.socket().close(); //Just trying to close the associated socket
// too because earlier approaches failed
channel.close();
}
当我从客户端发送第一条消息时,它已成功传送到服务器,客户端程序退出。然后麻烦开始了。当我再次初始化客户端并尝试 建立在与我第一次做的服务器相同的端口和地址,我得到了
即使我关闭了相关的通道/套接字,也会出现java.net.BindException:已在使用的地址:connect
异常。
我一直在更新ServerSocketChannel
和InetSocketAddress
对象,因为我的客户端实例必须在写入后关闭,我必须解除该通道,因为我关闭后无法重用通道,必须每次都制作一个新的物体。我的理论是因为channel
引用每次都被重新分配,孤立的对象变成GC肉,但由于close()方法显然不能正常工作,因此通道仍处于活动状态,直到GC收集它,我的端口将是挤兑。
尽管如此,我尝试在while循环之前保持ServerSocketChannel
和InetSocketAddress
对象的初始化,但是这没有帮助,并且在第一次写入之后发生了同样的异常,就像之前一样。
ServerSocketChannel channel = ServerSocketChannel.open();
InetSocketAddress serverSocket = new InetSocketAddress(host,port);
channel.bind(serverSocket);
while (true)
{
SocketChannel ch = channel.accept();
//read from a client
}
为清楚起见,以下是我从客户端连接的方式:
SocketChannel ch=SocketChannel.open();
ch.bind(new InetSocketAddress("localhost", 8077));
InetSocketAddress address=new InetSocketAddress("localhost",8079);
//the address and port of the server
System.out.print(ch.connect(address));
ByteBuffer buf=ByteBuffer.allocate(48);
buf.clear();
buf.put("Hellooooooooooooooooooooooooo".getBytes());
buf.flip();
while(buf.hasRemaining()) {
ch.write(buf);
}
ch.close();
答案 0 :(得分:3)
看起来你会混淆客户端和服务器。通常,服务器只启动一次,bind
到s端口。通常,当程序退出时,端口被释放时,不需要close
。显然,您必须关闭Socket
获得的ServerSocket.accept()
,但这是另一个故事。
我猜你已经被你的变量名混淆了(就像我刚开始的时候一样)。尝试根据他们的类型打电话给所有的东西,这里匈牙利人对我很有帮助。
我为测试而写的code是漫长的,愚蠢的,无聊的。但似乎有效。
答案 1 :(得分:0)
这样做可能也有帮助:
channel.setOption(StandardSocketOptions.SO_REUSEADDR,true);
搜索有关此选项的信息以了解更多信息。
答案 2 :(得分:-3)
对GC客户端套接字执行ch.close()。