繁体   English   中英

套接字客户端-服务器发送到服务器端后卡住

[英]Socket Client-Server gets stuck after sending to server side

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

服务器

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

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

您正在阅读一行:

String s = input.readLine();

但您没有写一行:

out.write(message);

为此添加一个行终止符。

然后:

int length = in.readInt();

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

我认为您的通讯协议有误:

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

    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");
        }
    }

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

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

byte[] buffer = new byte[length];
int bytesRead = in.read(buffer);
if (bytesRead != length) {
    ; // handle incomplete file transfer
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM