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

时间:2017-01-11 16:09:33

标签: java sockets printwriter datainputstream inputstreamreader

我的问题是,在我的客户端中,dis.read()正在返回-1,导致它永远不会真正收到该文件。我唯一能想到的是因为我在本节之前使用了PrintWriterBufferedReaderdis.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");
}

我有什么遗漏或遗忘的内容吗?我不是在说些什么或者没有清理什么?

1 个答案:

答案 0 :(得分:1)

好吧,我猜我发现了这个错误。我做了一些实验,发现如果多个对象试图从中读取,InputStream表现得很奇怪。在您的情况下,您的客户BufferedReader方法中的DataInputStreamreceiveFile很可能会通过尝试从同一inputStream读取来导致问题。我建议您使用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();
    }
}