Socket Client-Server在发送到服务器端后卡住了

时间:2015-12-23 08:18:22

标签: java sockets io

我需要为我的项目创建一个带套接字的文件传输应用程序。到目前为止,我已经编写了一个简单的客户端 - 服务器通信,但每当我尝试从客户端输出到服务器输入接收字符数据时,我的代码就会锁定。下面是代码:

服务器

public class ClientServer extends Thread {

Socket connection;
File file;

public ClientServer (Socket connection){
    this.connection = connection;
    this.start();
}

public void run(){
    try {
        System.out.println("Starting Client Thread...");
        BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        DataOutputStream output = new DataOutputStream(connection.getOutputStream());
        System.out.println("IO created...");
        System.out.println("input = " + input.readLine());

        String s = input.readLine();

        System.out.println(s);
        file = new File(s);

        if(file.isFile()){
            System.out.println("File " + s + " exists");

            FileInputStream fileOutput = new FileInputStream(file);
            byte[] buffer = new byte[1024*1024];
            int length = 0;
                while((length = fileOutput.read(buffer)) != -1){
                    output.write(buffer, 0, buffer.length);
                }
            System.out.println("File " + s + " sent.");
            fileOutput.close();
            output.close();
            input.close();
        } else {
            System.out.println(s + " is not a file");
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    finally{
        try {
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }               
}


public static void main(String[] args) throws IOException {

    int serverPort = 9000;

    ServerSocket server = new ServerSocket(serverPort);

        Socket connectionSocket = server.accept();

        ClientServer con = new ClientServer(connectionSocket);
}
}

客户端

public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub

    String ip = "localhost";
    int port = 9000;
    Socket clientSocket = new Socket(ip, port);


    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

    DataInputStream in = new DataInputStream(clientSocket.getInputStream());

    BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));

    System.out.println("Enter valid file name and press 'ENTER': ");

    String message = userInput.readLine();
    System.out.println("Sending message...");
    out.write(message);
    System.out.println("File name sent: " + message);

    int length = in.readInt();
    byte[] buffer = new byte[length];
    for(int i=0; i< length; i++){

        buffer[i] = in.readByte();
        System.out.println("Reading byte... " + buffer[i]);
    }
    File file = new File("C:/Users/Dominik/Desktop/lol/new.php");
    FileOutputStream fos = new FileOutputStream(file);
    fos.write(buffer);
    fos.close();

    clientSocket.close();
    System.out.println("Closing");
}
}

修改

这是我的输出,因为没有一个答案能解决我的问题(可能是我做错了):

客户端

Enter valid file name and press 'ENTER': C:\\Users\\Dominik\\Desktop\\Login.php //my input Sending message... File name sent: C:\\Users\\Dominik\\Desktop\\Login.php

服务器

Starting Client Thread... IO created... //Server should sysout the message sent, but it doesn't do so, its just stuck here

4 个答案:

答案 0 :(得分:1)

您尝试在客户端readInt,但在服务器端,您只发送文件内容。在发送文件之前,我看起来忘了发送文件大小。

答案 1 :(得分:1)

你正在读一句话:

String s = input.readLine();

但你不是在写一行:

out.write(message);

为此添加行终止符。

然后:

int length = in.readInt();

在这里,您正在读取一个永不发送的整数。发送它。

答案 2 :(得分:1)

我认为你的通信协议有错误:

在您的服务器中,连接后,您需要来自客户端的两个后续字符串

    System.out.println("input = " + input.readLine());

    String s = input.readLine();

但是客户端只发送一个(我认为你应该按照EJP的建议添加一个行终止符)

然后客户端需要一个整数,但服务器没有发送它:

    int length = in.readInt();

希望它有所帮助,祝你好运

修改(在12月23日编辑之后)

添加到您的客户端

out.flush();

之后

out.write(message + "\n");

然后修复协议。

我应用了你得到的所有建议,并让我开始工作

服务器:

    public class ClientServer extends Thread {

        Socket  connection;
        File    file;

        public ClientServer(Socket connection) {
            this.connection = connection;
            start();
        }

        @Override
        public void run() {
            try {
                System.out.println("Starting Client Thread...");
                BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                DataOutputStream output = new DataOutputStream(connection.getOutputStream());
                System.out.println("IO created...");
                // System.out.println("input = " + input.readLine());

                String s = input.readLine();

                System.out.println(s);
                file = new File(s);

                if (file.isFile()) {
                    System.out.println("File " + s + " exists");

                    FileInputStream fileInput = new FileInputStream(file);
                    output.writeInt((int) file.length());
                    byte[] buffer = new byte[1024 * 1024];
                    int length = 0;
                    while ((length = fileInput.read(buffer)) != -1) {
                        output.write(buffer, 0, length);
                    }
                    System.out.println("File " + s + " sent.");
                    fileInput.close();
                    output.close();
                    input.close();
                }
                else {
                    System.out.println(s + " is not a file");
                }

            }
            catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            catch (IOException e) {
                e.printStackTrace();
            }

            finally {
                try {
                    connection.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

        public static void main(String[] args) throws IOException {

            int serverPort = 9000;

            ServerSocket server = new ServerSocket(serverPort);

            Socket connectionSocket = server.accept();

            ClientServer con = new ClientServer(connectionSocket);
        }
    }

客户端:

    public class Client {

        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub

            String ip = "localhost";
            int port = 9000;
            Socket clientSocket = new Socket(ip, port);

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

            DataInputStream in = new DataInputStream(clientSocket.getInputStream());

            BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));

            System.out.println("Enter valid file name and press 'ENTER': ");

            String message = userInput.readLine();
            System.out.println("Sending message...");
            out.write(message + "\n");
            out.flush();
            System.out.println("File name sent: " + message);

            int length = in.readInt();
            byte[] buffer = new byte[length];
            for (int i = 0; i < length; i++) {

                buffer[i] = in.readByte();
                System.out.println("Reading byte... " + buffer[i]);
            }
            File file = new File("C:/test/fromServer.txt");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(buffer);
            fos.close();

            clientSocket.close();
            System.out.println("Closing");
        }
    }

答案 3 :(得分:0)

只是对所有有用答案的一小部分补充:
在服务器端写option个字节的文件 - length
不要使用buffer.length,这通常会导致output.write(buffer, 0, length);因为客户端会在收到java.net.SocketException: Broken pipe字节后立即关闭套接字,但服务器正在尝试写入整个1​​024 * 1024缓冲区。

同样在客户端,你可以摆脱for循环并接收像这样的文件内容

length