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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 13:10:10  来源:igfitidea点击:

TCP client/server program, DataInputStream / DataOutputStream issue

javasocketstcptcp-ip

提问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 writeBytesto write a string in the client and readUTFto 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, readUTFexpects the input to start with a 2 byte character count followed by a "modified UTF-8" encoding of the characters. But writeBytesjust writes 1 byte per character. Typically, readUTFwill attempt to read more bytes than writeByteswrote ... and the socket stream will freeze.

如果您查看这两种方法的 javadoc,您会发现您正在以一种格式编写,然后以另一种格式阅读。具体来说,readUTF期望输入以 2 字节字符计数开始,然后是字符的“修改后的 UTF-8”编码。但writeBytes每个字符只写 1 个字节。通常,readUTF将尝试读取比writeBytes写入更多的字节......并且套接字流将冻结。

You should use writeUTFinstead 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();
        }
    }
}