NIO客户端发出异常:java.net.ConnectException:连接被拒绝:无进一步信息
我修改了可用的示例代码 我的客户:NIO客户端发出异常:java.net.ConnectException:连接被拒绝:无进一步信息,java,nio,Java,Nio,我修改了可用的示例代码 我的客户: public class Client { public static void main(String[] args) { int n=10000; SocketTest [] st= new SocketTest[n]; for(int i=0;i<n;i++) st[i]= new SocketTest("hi"); for(int i=0;i<n;i++) new Thr
public class Client {
public static void main(String[] args) {
int n=10000;
SocketTest [] st= new SocketTest[n];
for(int i=0;i<n;i++)
st[i]= new SocketTest("hi");
for(int i=0;i<n;i++)
new Thread(st[i]).start();
}
}
class SocketTest implements Runnable {
private String message = "";
private Selector selector;
private int i;
public SocketTest(String message){
this.message = message;
}
@Override
public void run() {
SocketChannel channel;
try {
selector = Selector.open();
channel = SocketChannel.open();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_CONNECT);
channel.connect(new InetSocketAddress("127.0.0.1", 8511));
while (!Thread.currentThread().isInterrupted()){
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()){
SelectionKey key = keys.next();
keys.remove();
if (!key.isValid()) continue;
if (key.isConnectable()){
connect(key);
System.out.println("I am connected to the server");
}
if (key.isWritable()){
write(key);
}
if (key.isReadable()){
read(key);
}
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
close();
}
}
private void close(){
try {
selector.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void read (SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1000);
readBuffer.clear();
int length;
try{
length = channel.read(readBuffer);
} catch (IOException e){
System.out.println("Reading problem, closing connection");
key.cancel();
channel.close();
return;
}
if (length == -1){
System.out.println("Nothing was read from server");
channel.close();
key.cancel();
return;
}
readBuffer.flip();
byte[] buff = new byte[1024];
readBuffer.get(buff, 0, length);
//length=buff.length;
String fromserver = new String(buff,0,length,"UTF-8");
length = fromserver.length();
System.out.println("Server said: "+fromserver);
key.interestOps(SelectionKey.OP_WRITE);
}
private void write(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
i++;
message = "location now "+i;
try{
Thread.sleep(5000);
}
catch(InterruptedException ie)
{
System.out.println(""+ie);
}
channel.write(ByteBuffer.wrap(message.getBytes()));
// lets get ready to read.
key.interestOps(SelectionKey.OP_READ);
}
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
try
{
if(!channel.finishConnect())
System.out.println("* Here *");
}
catch(ConnectException e)
{
System.out.println("BP 1");
e.printStackTrace();
//channel.close();
//key.cancel();
//return;
}
/*if (channel.isConnectionPending()){
while(!channel.ffinishConnect()){
System.out.println("not connected");
}
}*/
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_WRITE);
}
}
公共类客户端{
公共静态void main(字符串[]args){
int n=10000;
SocketTest[]st=新SocketTest[n];
对于(int i=0;i我相信您使用500个线程获得的ConnectException
不是来自SocketTest.connect()
。它可能来自任何其他IO方法
为了快速修复(并说服自己),您可以在主try catch
块中显式捕获ConnectException
,如下所示:
try {
// connect, write, and read ...
} catch (ConnectException ce) { // <-- catch the more specific Exception first
System.out.println("You caught a ConnectException.");
} catch (IOException e1) { // <-- you originally only caught this
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
试试看{
//连接、写入和读取。。。
}捕获(连接异常){/连接异常:拒绝连接
意味着在您尝试连接的IP:端口或服务器的侦听积压队列填满的某些平台上没有侦听任何内容。如果抛出了它,并且您正确捕获了它,您肯定会捕获它。您必须详细介绍实际发生的情况以及实际捕获的内容ode看起来需要进一步的帮助
但是,您还有许多其他问题:
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
try
{
if(!channel.finishConnect())
System.out.println("* Here *");
此时,如果finishConnect()
返回false,则应返回。您不应中断并重新注册OP\u WRITE的通道。
连接仍处于挂起状态。打印“*此处*”
也很无效。请尝试打印一些有意义的内容
}
catch(ConnectException e)
{
System.out.println("BP 1");
e.printStackTrace();
//channel.close();
此时你当然应该关闭通道。它对人类或野兽没有任何用处
//key.cancel();
关闭频道将取消密钥。如果遇到,请删除
//return;
如上所述,此时您当然应该返回
}
/*if (channel.isConnectionPending()){
while(!channel.ffinishConnect()){
System.out.println("not connected");
}
}*/
摆脱这个积垢。在非阻塞模式下旋转循环是不合适的。甚至不要把它作为评论放在一边:一些白痴可能会在稍后出现并玩着把它放回去的游戏
channel.configureBlocking(false);
频道已处于非阻塞模式。否则您将不在这里。请删除
channel.register(selector, SelectionKey.OP_WRITE);
另一种方法是key.interesttops(SelectionKey.OP_WRITE);
沉睡在网络代码中简直是浪费时间。它解决不了任何问题
您假设write()
完全成功,并且忽略它返回的计数
您使用的参考资料质量相当差:
- 关于
write()
的注释与上述相同
flip()
- 取消键将关闭通道
- 您不必清除全新的
ByteBuffer,
,但在任何情况下,为每次读取分配ByteBuffer
都是不好的做法
ServerSocketChannel.accept()
可以返回null。
- 读取后显示字符串的代码不正确
- 当键具有附件时,无需使用
映射
- 不管怎样,当NIO是可中断的时,没有必要继续测试
Thread.interrupted()
- 没有必要因为一个频道上的一个
IOException
而关闭所有内容
尝试找到更好的方法。尝试使用命令执行Telnet-
telnet [host IP] [port]
问题可能是防火墙阻止端口。您使用的是windows还是linux?感谢您的解释。服务器肯定已启动并正在侦听。我不知道侦听队列如何填满。请参阅我的编辑。如果您的服务器不以最快的速度接受连接,侦听队列可能会填满。这听起来像是问题:何时Windows待办事项队列已满,但开始拒绝连接。1)你能告诉我积压工作队列最常见的大小是什么吗?我读到非服务器Windows机器的是5,服务器机器的是200。我对吗?2)我在创建新客户端时设置了线程睡眠,即100个客户端,然后5秒睡眠,然后是100个客户端。这对大约4000个线程有效。但当我创建10000个线程时,大约有8500个线程存活下来。For rest连接被拒绝。您能告诉我原因是什么吗?我认为积压队列不能作为最初处理它们的原因?@cruxioneffux(1)50或系统默认值。(2)当您将睡眠放入时,积压队列不会比接受循环提前太多。当您将它们取出时,接受循环无法跟上,因此积压队列已满。查看是否可以加快接受循环:例如,将线程初始化移动到run()中
method。它将来自SocketChannel.finishConnect()。