以下代码是更大尝试的一部分;它试图在服务器和客户端之间传输文件的细节,并且失败了。服务器将3个元素写入socket,客户端应该接收相同的3个元素。读取第一个元素后的客户端块。我做错了什么?!?
public class SocketIssues {
static void client() throws Exception {
new Thread() {
@Override
public void run() {
try {
Thread.sleep(1000); // enough time for server to open its socket
Socket s = new Socket("localhost", 50001);
final DataInputStream dis = new DataInputStream(s.getInputStream());
final BufferedReader in = new BufferedReader(new InputStreamReader(dis));
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + in.readLine());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
static void server() throws Exception {
ServerSocket ss = new ServerSocket(50001);
Socket s = ss.accept();
System.out.println("SERVER: client connected");
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(dos));
long l = 2194;
String nume = "The file name";
out.write("FILE1" + System.lineSeparator());
out.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: done sending" + System.lineSeparator());
}
public static void main(String[] args) throws Exception {
client();
server();
}
}
答案 0 :(得分:1)
尝试仅使用DataOutputStream
而不是在数据和缓冲的编写器之间混合,并使用读/写UTF()方法,就像您已经在使用最后一个对象一样:
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
long l = 2194;
String nume = "The file name";
dos.writeUTF("FILE1");
dos.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: fisier trimis" + System.lineSeparator());
然后在客户端:
final DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + dis.readUTF());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
基本上,有两层缓冲正在进行中。当你从BufferedReader调用readLine()
时,它可能会从底层流中窃取更多的字节,因为这就是它应该做的事情。然后,当你回到DataInputStream并尝试读取一个对象时,前导码就消失了(BufferedReader偷了它),并且它会阻塞等待它,尽管流中有字节。