java - 客户端套接字不会从服务器接收数据

标签 java sockets printwriter datainputstream inputstreamreader

我的问题是,在我的客户端中,dis.read() 返回-1,导致它永远不会真正接收文件。我唯一能想到的是,因为我在本节之前使用了 PrintWriterBufferedReader,所以 dis.read() 认为所有数据均已收到。

客户端代码:

public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
    Socket client = new Socket(serverAddress, port);
    client.setSoTimeout(5000);
    PrintWriter out = new PrintWriter(client.getOutputStream(), true);
    BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));

    try {
        out.println("101|" + fileName + "\n");

        if (input.readLine().equals("201")) {
            int br;
            byte[] data = new byte[4096];

            DataInputStream dis = new DataInputStream(client.getInputStream());
            FileOutputStream fos = new FileOutputStream(fileOut);

            while ((br = dis.read(data, 0, data.length)) != -1){
                fos.write(data, 0, br);
            }

            fos.close();
            dis.close();
        }
    } catch (SocketTimeoutException ste) {
        ste.printStackTrace();
        client.close();
    }
}

服务器代码:

private void sendFile(String filename, Socket client) throws IOException {
    int br;
    byte[] data = new byte[4096];
    PrintWriter out = new PrintWriter(client.getOutputStream(), true);

    out.println("201\n");

    DataOutputStream dos = new DataOutputStream(client.getOutputStream());
    FileInputStream fis = new FileInputStream(MeshFS.properties.getProperty("repository") + filename);

    while ((br = fis.read(data, 0, data.length)) != -1) {
        dos.write(data, 0, br);
        dos.flush();
    }

    fis.close();
    dos.close();
}

private String receiveRequest(Socket client) {
    String requestPart;
    String requestFull = "";
    try {
        BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));

        while (((requestPart = input.readLine()) != null) && (requestFull.length() < 2048)) {
            if (requestPart.equals("")) break;
            requestFull = requestFull + requestPart;
        }

        return requestFull;
    } catch (IOException ioe) {
        return requestFull;
    }
}

private void processRequest(String request, Socket out) {

    if (request != null) {
        try {
            String[] requestParts = request.split("\\|");
            if (requestParts[0].equals("101")) {            //101:Get file
                sendFile(requestParts[1], out);

            } else {
                badRequest(out, request);
            }
        } catch (Exception e) {
            badRequest(out, request);
            e.printStackTrace();
        }
    }
}

    public void run() {
        while (!Thread.interrupted()) {
            try {
                server.setSoTimeout(1000);
                Socket client = server.accept();
                client.setSoTimeout(timeout);
                processRequest(receiveRequest(client), client);
                client.close();
            } catch (SocketTimeoutException ste) {
            } catch (IOException io) {
                io.printStackTrace();
            }
        }
        System.out.println("Socket closed");
}

有什么我遗漏或忘记包含的内容吗?我是不是没有冲洗某些东西或没有清除某些东西?

最佳答案

好吧,我想我已经发现错误了。我做了一些实验,发现如果多个对象尝试从中读取,InputStream 的行为会很奇怪。在您的情况下,客户端的 receiveFile 方法中的 BufferedReaderDataInputStream 很可能通过尝试从相同的 读取而导致问题>输入流。我建议使用 DataInputStream 来读取第一行,这样您就不必创建 BufferedReader。尽管 DataInputStream.readLine() 方法已被弃用,但它在您的情况下仍然应该表现良好。

我编辑了客户端 receiveFile 方法以使用 DataInputStream 读取第一行。希望它有效!

public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
    Socket client = new Socket(serverAddress, port);
    client.setSoTimeout(5000);
    PrintWriter out = new PrintWriter(client.getOutputStream(), true);
    DataInputStream dis = new DataInputStream(client.getInputStream());

    try {
        out.println("101|" + fileName + "\n");

        if (dis.readLine().equals("201")) {
            int br;
            byte[] data = new byte[4096];

            FileOutputStream fos = new FileOutputStream(fileOut);

            while ((br = dis.read(data, 0, data.length)) != -1){
                fos.write(data, 0, br);
            }

            fos.close();
            dis.close();
        }
    } catch (SocketTimeoutException ste) {
        ste.printStackTrace();
        client.close();
    }
}

关于java - 客户端套接字不会从服务器接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41595542/

相关文章:

java - 使用 docker 执行 mkdir 命令

c - SO_REUSEPORT 与 epoll 和多进程

java - 发送紧急数据后 TCP 连接被重置

java - PrintWriter 与 FileWriter 在以下上下文中的比较

java - sql查询不更新JTable

Java:inetaddress 到 String 转换

java - Comparable 类不能比较什么?

c++ - 非阻塞发送功能

java - 将 PrinterWriter 与字符串 ArrayList 结合使用

java - 使用 printwirter attend 方法的 while 循环仅写入最后搜索的单词