我已经写了最小的例子,但还是太长了,所以让我知道我应该把链接贴到Pastebin上。
服务器:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class Srv {
static final int PORT = 9001;
static final String HOST = "127.0.0.1";
public static void runInstance() {
try (AsynchronousServerSocketChannel asynchronousServerSocketChannel =
AsynchronousServerSocketChannel.open()) {
if (asynchronousServerSocketChannel.isOpen()) {
asynchronousServerSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024);
asynchronousServerSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
asynchronousServerSocketChannel.bind(new InetSocketAddress(HOST, PORT));
System.out.println(String.format("Launched master on %s:%d", HOST, PORT));
asynchronousServerSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel result, Void attachment) {
asynchronousServerSocketChannel.accept(null, this);
try {
result.read(ByteBuffer.allocate(1024));
System.out.println("Conn from:" + result.getRemoteAddress());
} catch (Exception exn) {
exn.printStackTrace();
} finally {
try {
result.close();
} catch (IOException exn) {
exn.printStackTrace();
}
}
}
@Override
public void failed(Throwable exn, Void attachment) {
asynchronousServerSocketChannel.accept(null, this);
throw new UnsupportedOperationException("can't accept");
}
});
System.in.read();
} else {
System.out.println("The asynchronous server-socket channel cannot be opened");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}客户端:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import static java.lang.Thread.sleep;
public class Wrk {
static final int PORT = 9001;
static final String HOST = "127.0.0.1";
public static void runInstance() throws InterruptedException {
sleep(1000); //HERE
try(AsynchronousSocketChannel asynchronousSocketChannel = AsynchronousSocketChannel.open()) {
if (asynchronousSocketChannel.isOpen()) {
asynchronousSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024);
asynchronousSocketChannel.setOption(StandardSocketOptions.SO_SNDBUF, 1024);
asynchronousSocketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
asynchronousSocketChannel.connect(new InetSocketAddress(HOST, PORT), null,
new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
try {
System.out.println("Connected to: " + HOST + PORT);
asynchronousSocketChannel.read(ByteBuffer.allocate(1024)).get();
} catch (Exception exn) {
exn.printStackTrace();
} finally {
try {
asynchronousSocketChannel.close();
} catch (IOException exn) {
exn.printStackTrace();
}
}
}
@Override
public void failed(Throwable throwable, Void o) {
System.out.println("Connection cannot be established");
}
});
sleep(1000); //AND HERE
} else {
System.out.println("The asynchronous socket channel cannot be opened");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}要运行的样板:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread srv = new Thread(new Runnable() {
@Override
public void run() {
Srv.runInstance();
}
});
srv.start();
Thread wrk1 = new Thread(new Runnable() {
@Override
public void run() {
try {
Wrk.runInstance();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
wrk1.start();
}
}因此,如果我有这样的代码,它会给出以下输出:
Launched master on 127.0.0.1:9001
Connected to: 127.0.0.1 9001
Conn from:/127.0.0.1:50415但是如果我在Srv.runInstance()中删除这些sleep(),我会得到:
Connection cannot be established
Launched master on 127.0.0.1:9001
Conn from:/127.0.0.1:50438那么,这是否意味着客户端连接到服务器,但服务器拒绝?我不清楚这里发生了什么,文档也很差,所以我不知道去哪里寻找解决方案。
发布于 2013-10-07 01:10:16
我在所发布的代码中看到的唯一睡眠是在Wrk.runInstance中。但是,输出的顺序清楚地说明了发生了什么。您的工作正在尝试在服务器完全初始化之前连接到服务器。正如您在输出中看到的,“连接消息”位于“启动的主节点”之前。
服务器需要一点时间才能启动,因此在没有休眠的情况下,您的客户端正在尝试连接到尚未存在的东西。
https://stackoverflow.com/questions/19211475
复制相似问题