我修改了此处可用于客户端和服务器My Client的示例代码:
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);
}
}
我通过创建多个线程在同一台机器上创建多个客户端。线程的数量由n的值决定。当我运行少量客户端时,我不会遇到任何问题,但当我使用n运行500个(即500个客户端线程)时,一些线程会正确运行,但在一些线程中,我会遇到以下情况:java。网连接异常:连接被拒绝:sun没有进一步信息。nio。ch.SocketChannelImpl。sun上的checkConnect(本机方法)。nio。ch.SocketChannelImpl。在SocketTest完成连接(未知源)。在SocketTest连接(Client.java:143)。运行(Client.java:61)
第143行是:if(!channel.finishConnect())
所以当我读到这个方法的留档时,它说它抛出:
NoConnectionPendingException-如果此通道未连接且连接操作尚未启动。
ClosedChannelException-如果此通道已关闭。
AsynchronousCloseException-如果另一个线程在连接操作进行时关闭此通道。
ClosedByinterrupException-如果在连接操作进行时另一个线程中断当前线程,从而关闭通道并设置当前线程的中断状态。
IOException-如果发生其他输入/输出错误。
但是异常是ConnectException。我试图捕捉它,但它没有进入捕捉块。
任何帮助都将不胜感激。谢谢编辑:我正在windows上工作。我尝试更改n的值,看看创建了多少个客户端,导致了多少个异常,这些都是结果(我知道在每次测试后等待更多的时间将允许打开更多的套接字,因为在每次测试后,范围将在time\u WAIT后释放):
n个已连接的客户端(通过在服务器上保持计数)1000 522 2000 568 3000 626 4000 600(可能在连续运行之前我给的时间更少)5000 1345 6000 1389
我的问题是,只有这么多客户端才能连接。谁能为客户机服务器NIO推荐更好的参考资料吗。
编辑2
正如EJP在评论中提到的那样,窗口积压工作队列已满。我修改了客户端代码以生成100个线程,然后Hibernate5秒,这样队列上的负载就不会太大,大多数连接都成功了(然而,当建立10000个连接时,一些连接仍然失败)。
我相信您在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 {
至于为什么会发生这种情况,我可以告诉你,我目前正在增加数百个线程来测试SOAP服务。我还到处都是断开的连接,因此,对于如此大量的并发线程,这可能是意料之中的。
匿名用户
连接异常:连接被拒绝意味着在您试图连接的IP:端口或服务器的侦听积压队列中填满的某些平台上没有侦听任何内容。如果它被抛出,你正确地抓住了它,你一定会抓住它。为了获得进一步的帮助,您必须扩展实际发生的情况以及实际的catch代码。
但是,您还有许多其他问题:
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
try
{
if(!channel.finishConnect())
System.out.println("* Here *");
此时,如果finishConnect()返回false,则应该返回。您不应通过并重新注册用于操作单元写入的通道
连接仍处于挂起状态。在这里打印“*”也是徒劳的。试着打印一些有意义的东西。
}
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);
另一种方法是按键。兴趣(SelectionKey.OP\u WRITE)
睡在网络代码中简直是浪费时间。它不能解决任何问题。
您假设write()
完全成功,并且忽略它返回的计数。
您使用的是相当差的质量参考:
- 关于
write()
的相同备注如上所述
试着找到更好的。
我正在使用Spring 5网络流量、SpringBoot 2和Reactive MongoDB构建一个POC。在使用maven插件构建项目时,我得到了如下错误MongoDB连接错误:- 以下是我的申请表。属性文件:- 波姆。xml:- 请告知这里可能存在什么问题?我是否需要在我的机器上显式安装MongoDB并在运行此项目之前运行它。我相信MongoDB实例将自行运行,因为SpringBoot将在运
例外情况: 原因:java.net.connectException:拒绝连接:在org.springframework.web.client.resttemplate.doexecute连接(resttemplate.java:359)
我正在尝试使用java邮件api,并且在servlet中有以下代码用于sen mail。我找不到解决错误的方法。 我的控制台中出现以下错误: 原因:java.net.ConnectException:连接被拒绝:java.net.DualStackPlainSocketImpl.connect0(本机方法)java.net.DualStackPlainSocketImpl.socketConnec
我使用neo4j 2.2.4 我尝试了这个程序,这是我的测试代码 这是我的错误信息, {“Name”:[“John”]}线程“main”com中出现异常。太阳运动衫应用程序编程接口。客户ClientHandlerException:java。网连接异常:连接被拒绝:在com上连接。太阳运动衫客户URL连接。URLConnectionClientHandler。句柄(URLConnectionCli
问题内容: 我怎样才能捕捉到异常? 问题答案: 通过捕获 所有 异常,并在属性不等于111的情况下重新引发它。或者,更好的是,使用常量代替:
我正在尝试运行https://github.com/hazelcast/hazelcast-nodejs-client的“使用客户端”部分中提供的基本示例代码 我收到连接拒绝错误。我在我的Mac和PC机器上尝试了这个,结果相同。它们运行的是Node v6.9.1。我没有任何特殊的防火墙设置。甚至尝试完全打开Windows防火墙。 我错过了什么吗? 首先,我创建了一个空节点项目,然后: 然后创建了一