java TCP 客户端/服务器程序,DataInputStream / DataOutputStream 问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28187038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TCP client/server program, DataInputStream / DataOutputStream issue
提问by Kishore-Kumar Kailainathan
I'm trying to write a simple TCP client server connection. The server spawns a thread for each new client connection, and each thread talks to a client. I'm using DataInputStream and DataOutputStream classes, upon dis.readUTF() the server thread comes to a halt. I tried using BufferedReader and PrintStream/Printwriter, still the same issue. Please look for System.out.println("not here now"), that line preceding it blocks the execution.
我正在尝试编写一个简单的 TCP 客户端服务器连接。服务器为每个新的客户端连接生成一个线程,每个线程都与一个客户端对话。我正在使用 DataInputStream 和 DataOutputStream 类,在 dis.readUTF() 上,服务器线程停止。我尝试使用 BufferedReader 和 PrintStream/Printwriter,仍然是同样的问题。请查找 System.out.println("not here now"),它前面的那行会阻止执行。
/*
TCP client
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPClient {
public TCPClient() {
// TODO Auto-generated constructor stub
}
public static void main (String args[]) throws UnknownHostException, IOException {
Socket socket = new Socket("localhost", 9701);
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
//char[] buffer = new char[100];
boolean stop = false;
while (!stop) {
System.out.println("here");
output.writeBytes("hello server");
String response = "-WTF-";
System.out.println("here");
response = input.readUTF();
System.out.println("not here now");
if (response == "kill") {
stop = true;
} else {
System.out.println("5");
output.writeBytes("talk to me");
System.out.println("received" + response);
}
}
socket.close();
}
}
/* TCP server */
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer extends Thread {
final static int TCP_SERVER_PORT = 9701;
private Socket socket;
public TCPServer(Socket sock) {
// TODO Auto-generated constructor stub
socket = sock;
}
public void run() {
System.out.println(this.socket.getPort() + " working or sleeping for 5 seconds");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataInputStream clientinp;
DataOutputStream clientout;
try {
clientinp = new DataInputStream(socket.getInputStream());
clientout = new DataOutputStream(socket.getOutputStream());
System.out.println("here");
while (true) {
System.out.println("here now");
String sentence = clientinp.readUTF();
System.out.println("not here now");
System.out.println(sentence);
clientout.writeBytes(sentence);
}
}
catch (IOException e) {
System.out.println(e.getStackTrace());
}
finally {
try {
this.socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* other logic
*/
}
public static void main(String args[]) throws IOException {
ServerSocket serversocket;
serversocket = new ServerSocket(TCP_SERVER_PORT);
while (true) {
Socket clientsocket = serversocket.accept();
new TCPServer(clientsocket).start();
}
}
}
回答by Stephen C
You are using writeBytes
to write a string in the client and readUTF
to read the same string in the server.
您正在使用writeBytes
在客户端中写入字符串并readUTF
在服务器中读取相同的字符串。
If you look at the javadocs for those two methods you will see that you are writing in one format and then reading in another. Specifically, readUTF
expects the input to start with a 2 byte character count followed by a "modified UTF-8" encoding of the characters. But writeBytes
just writes 1 byte per character. Typically, readUTF
will attempt to read more bytes than writeBytes
wrote ... and the socket stream will freeze.
如果您查看这两种方法的 javadoc,您会发现您正在以一种格式编写,然后以另一种格式阅读。具体来说,readUTF
期望输入以 2 字节字符计数开始,然后是字符的“修改后的 UTF-8”编码。但writeBytes
每个字符只写 1 个字节。通常,readUTF
将尝试读取比writeBytes
写入更多的字节......并且套接字流将冻结。
You should use writeUTF
instead of writeBytes
...
你应该使用writeUTF
而不是writeBytes
...
回答by chris
Stephen C is right. I did some small modifications but the reason was 'use read* when using write* on the other side'.
斯蒂芬 C 是对的。我做了一些小的修改,但原因是“在另一侧使用 write* 时使用 read*”。
Here's the running code:
Client:
这是运行代码:
客户端:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPClient {
public TCPClient() {
}
public static void main(String args[]) throws UnknownHostException, IOException {
Socket socket = new Socket("localhost", 9701);
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
boolean stop = false;
while (!stop) {
System.out.println("client->server: hello...");
output.writeUTF("hello");
System.out.println("client: waiting...");
String response = input.readUTF();
System.out.printf("client: got response: %s\n", response);
}
socket.close();
}
}
Server:
服务器:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer extends Thread {
final static int TCP_SERVER_PORT = 9701;
private Socket socket;
public TCPServer(Socket sock) {
socket = sock;
}
public void run() {
System.out.println(this.socket.getPort() + " working or sleeping for 5 seconds");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
DataInputStream clientinp;
DataOutputStream clientout;
try {
clientinp = new DataInputStream(socket.getInputStream());
clientout = new DataOutputStream(socket.getOutputStream());
while (true) {
System.out.println("reading...");
String sentence = clientinp.readUTF();
System.out.printf("read: %s", sentence);
clientout.writeUTF(String.format("answer: %s", sentence));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) throws IOException {
ServerSocket serversocket;
serversocket = new ServerSocket(TCP_SERVER_PORT);
while (true) {
Socket clientsocket = serversocket.accept();
new TCPServer(clientsocket).start();
}
}
}