gpt4 book ai didi

java - 将 75 个客户端连接到服务器后连接被拒绝

转载 作者:太空宇宙 更新时间:2023-11-04 14:16:35 24 4
gpt4 key购买 nike

我使用以下代码开发了一个服务器 channel 套接字:

public class EchoServer {
private static final int BUFFER_SIZE = 1024;

private final static int DEFAULT_PORT = 9090;

private long numMessages = 0;

private long loopTime;

private InetAddress hostAddress = null;

private int port;

private Selector selector;

// The buffer into which we'll read data when it's available
private ByteBuffer readBuffer = ByteBuffer.allocate(BUFFER_SIZE);

int timestamp=0;

public EchoServer() throws IOException {
this(DEFAULT_PORT);
}

public EchoServer(int port) throws IOException {
this.port = port;
hostAddress = InetAddress.getByName("127.0.0.1");
selector = initSelector();
loop();
}

private Selector initSelector() throws IOException {
Selector socketSelector = SelectorProvider.provider().openSelector();

ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);

InetSocketAddress isa = new InetSocketAddress(hostAddress, port);
serverChannel.socket().bind(isa);
serverChannel.register(socketSelector, SelectionKey.OP_ACCEPT);
return socketSelector;
}

private void loop() {
for (;true;) {
try {
selector.select();
Iterator<SelectionKey> selectedKeys = selector.selectedKeys()
.iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
// Check what event is available and deal with it
if (key.isAcceptable()) {
accept(key);
} else if (key.isWritable()) {
write(key);
}
}
Thread.sleep(3000);
timestamp+=3;
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}



}
}

private void accept(SelectionKey key) throws IOException {

ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();

SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
socketChannel.setOption(StandardSocketOptions.TCP_NODELAY, true);
// socketChannel.register(selector, SelectionKey.OP_READ);
socketChannel.register(selector, SelectionKey.OP_WRITE);

System.out.println("Client is connected");
}

private void write(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer dummyResponse = ByteBuffer.wrap(("ok:" + String.valueOf(timestamp)) .getBytes("UTF-8"));

socketChannel.write(dummyResponse);
if (dummyResponse.remaining() > 0) {
System.err.print("Filled UP");
}
System.out.println("Message Sent");
// key.interestOps(SelectionKey.OP_READ);
}

}

如您所见,我在 localhost 端口 9090 上运行它。为了测试重连接的代码,我开发了一个测试应用程序,每秒运行一个新线程并连接到服务器。这是我的测试应用程序的代码:

    public class Main {

/**
* @param args
*/
public static void main(String[] args) {
int i = 0;
try {
while (i < 10000) {
RunnableDemo temp = new RunnableDemo("Thread-"
+ String.valueOf(i));
temp.start();
i++;
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class RunnableDemo implements Runnable {
private Thread t;
private String threadName;

InetAddress host = null;
int port = 9090;

RunnableDemo(String name) {
threadName = name;
System.err.println("Creating " + threadName);

}

public void run() {
System.err.println("Running " + threadName);
try {
SocketChannel socketChannel = SocketChannel.open();

socketChannel.connect(new InetSocketAddress(host, port));

while (!socketChannel.finishConnect())
;

System.out.println("Thread " + threadName + " Connected");
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (true) {
if (socketChannel.read(buffer) > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.limit()];
buffer.get(bytes);
System.out.println(threadName+ ":" + new String(bytes));
buffer.clear();
}
}

} catch (Exception e) {
System.out.println("Thread " + threadName + " interrupted.");
e.printStackTrace();
}
System.out.println("Thread " + threadName + " exiting.");
}

public void start() {
System.out.println("Starting " + threadName);
try {
host = InetAddress.getByName("127.0.0.1");
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}

}

测试应用程序运行,但只有 75 个线程可以连接到服务器,第 75 个线程之后的所有线程都显示以下异常:

java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect0(Native Method)
at sun.nio.ch.Net.connect(Unknown Source)
at sun.nio.ch.Net.connect(Unknown Source)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at net.behboodi.client.RunnableDemo.run(Main.java:48)
at java.lang.Thread.run(Unknown Source)

套接字的并发连接数有限制吗?或者使用端口 127.0.0.1 和本地主机是否有任何限制?另一个想法是,Java 应用程序或 JVM 可能无法创建超过 75 个线程。

我搜索了所有这些,但没有找到任何答案来告诉我上述原因是什么是我的主要问题,以及如何修复代码以便我可以使用超过 10000 个并发线程测试应用程序?

最佳答案

摆脱 sleep 。选择器已经阻塞。睡在网络代码中简直就是浪费时间。注意:(1) 您不会在阻塞模式下调用 finishConnect(),(2) 您没有将线程连接到 ServerChannel,而是将客户端套接字连接到服务器套接字,(3) 您的客户端代码不处理流结束,以及 (4) 这不是回显服务器。 – EJP

关于java - 将 75 个客户端连接到服务器后连接被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27647599/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com