Java 套接字编程:输入流似乎阻塞了输出流
我试图编写一个服务器-客户机通信应用程序,它使用两个独立的线程,一个用于输入,一个用于输出。不过,我遇到了一个奇怪的“死锁”问题:当一个线程读取输入,但客户端没有发送任何内容时,线程停止(因为它正在等待输入)。但是,由于某种原因,当输入线程被阻塞时,输出线程不能写入任何内容 此代码示例对此进行了说明:Java 套接字编程:输入流似乎阻塞了输出流,java,sockets,inputstream,blocking,outputstream,Java,Sockets,Inputstream,Blocking,Outputstream,我试图编写一个服务器-客户机通信应用程序,它使用两个独立的线程,一个用于输入,一个用于输出。不过,我遇到了一个奇怪的“死锁”问题:当一个线程读取输入,但客户端没有发送任何内容时,线程停止(因为它正在等待输入)。但是,由于某种原因,当输入线程被阻塞时,输出线程不能写入任何内容 此代码示例对此进行了说明: import java.io.*; import java.net.*; import java.nio.*; import java.nio.channels.*; public class
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class TestServer {
public static void main(String... args) throws IOException {
/* Creates a server socket that lurks about our port waiting for connections */
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress(4114));
while(true){
SocketChannel connectionChannel = serverChannel.accept();
if(connectionChannel != null){
final Socket connection = connectionChannel.socket();
new Thread(){
public void run(){
try {
System.out.println("READING");
System.out.flush();
// If the next line is commented out, nothing blocks
connection.getInputStream().read();
System.out.println("DONE READING");
System.out.flush();
} catch (Exception e){
e.printStackTrace();
}
}
}.start();
new Thread(){
public void run(){
try {
System.out.println("WRITING");
System.out.flush();
new DataOutputStream(connection.getOutputStream()).writeBytes("AUGH!!!");
//connection.getOutputStream().write(5);
System.out.println("DONE WRITING");
System.out.flush();
} catch (Exception e){
e.printStackTrace();
}
}
}.start();
break;
}
}
}
}
和客户端代码:
import java.net.*;
import java.io.*;
public class TestClient {
public static void main(String... args) throws IOException {
Socket connection = new Socket("127.0.0.1", 4114);
while(true){
System.out.println(connection.getInputStream().read());
}
}
}
上面的代码示例会阻塞,但如果服务器中的行被注释掉,则不会。为什么呢?套接字是否仅限于同时等待输入/输出?发生了什么事?我不知道你为什么会看到这一点,但这与使用频道有关 如果将此代码替换为
ServerSocket ss = new ServerSocket(4114);
Socket connection = ss.accept();
它可以按照您的意愿工作。我对这种行为感到惊讶,但在两个单独的线程中处理单个客户机的输入和输出对我来说似乎很奇怪。大多数基于线程的系统对每个客户端使用一个线程。(我还认为,
nio
的一个重要调用功能是,它允许您在不使用线程的情况下编写服务器——它是线程安全的吗?)我还注意到,如果我将带有DataOutputStream的行切换为只使用直接OutputStream的行,那么事情就开始工作了。DataOutputStream是否发送了某种类型的头文件,将这些东西搞砸了?发生了什么?我相信DataOutputStream不会发送任何头数据,ObjectOutputStream当然会发送,但这仍然会影响您的问题。