简体   繁体   English

Java套接字连接重置

[英]java socket connection reset

I am trying to make simple server client app that lets the client send a file to the server then the server sends acknowledgement message that it received the file 我正在尝试制作一个简单的服务器客户端应用程序,该应用程序允许客户端将文件发送到服务器,然后服务器发送确认消息,表示已收到文件

this is the server class. 这是服务器类。

public class Server {

public static void main(String[] args) {
    try {
        ServerSocket server=new ServerSocket(9090);
        while(true){
            Socket clientSocket=server.accept();
            ClientThread client=new ClientThread(clientSocket);
            client.start();
        }
    } catch (IOException e) {
        System.out.println(e.toString());
    }

}

}

ClientThread class ClientThread类

public class ClientThread extends Thread {

private Socket socket;// socket to connect through
private BufferedInputStream SocketInput;// stream to read from socket
private BufferedOutputStream FileOutput;// stream to write file through it
private PrintWriter SocketOutput; // print writer to write through socket

public ClientThread(Socket socket){// constructor
    this.socket=socket;
}

public void run(){
    try {
        //get socket input stream
        SocketInput=new BufferedInputStream(socket.getInputStream());

        //get socket output stream
        SocketOutput=new PrintWriter(socket.getOutputStream(),true);

        // get the file from client
        int NBytes=0;
        byte[] data=new byte[1024];

        FileOutput=new BufferedOutputStream(new   FileOutputStream("C:/Users/mohamed/Desktop/Download/band.jpg"));      
        while((NBytes=SocketInput.read(data))!=-1){
            FileOutput.write(data,0,NBytes);
            FileOutput.flush();
        }

        // send ack. that file has been received
        SocketOutput.println("File has been sent sucessfully");

        //close all streams
        FileOutput.close();
        SocketInput.close();
        SocketOutput.close();
        socket.close();

    }
    catch (IOException e) {
        System.out.println(e.toString());
    }
}
}

Client class 客户类

public class Client {

public static void main(String[] args) {

    // file will be sent
    File f=new File("D:/images/band.jpg");

    try {

        // get address of local host
        InetAddress serverAddress=InetAddress.getLocalHost();

        //create socket
        Socket socket=new Socket(serverAddress,9090);

        // create streams
        BufferedInputStream input=new BufferedInputStream(new FileInputStream(f));
        BufferedOutputStream output=new BufferedOutputStream(socket.getOutputStream());
        BufferedReader p=new BufferedReader(new InputStreamReader(socket.getInputStream()));

        // send the file
        byte[] data=new byte[1024];
        int Nbytes=0;

        while((Nbytes=input.read(data))!=-1){
            output.write(data,0,Nbytes);
            output.flush();
        }

        // read the ack. and print it
        System.out.println(p.readLine());

        //close streams & socket
        p.close();
        input.close();
        output.close();
        socket.close();

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

}

what i get when i run the server and the client i got nothing , if i stop the client the server app types in the console exception connection reset , but if i remove the part of the acknowledgement the file is received and nothing goes wrong ,what is the problem? 运行服务器和客户端时得到的结果是什么,如果停止客户端,则控制台异常连接重置中的服务器应用程序类型会消失,但是如果我删除了确认部分,那么文件将被接收并且没有任何问题,这是什么是问题吗?

You're deadlocked. 你陷入僵局。 The client is reading the socket to end of stream, and you haven't closed the socket, so there is no end of stream, so when you go to read the ACK line both peers are reading. 客户端正在读取套接字到流的末尾,并且您没有关闭套接字,因此没有流的末尾,因此当您读取ACK线时,两个对等方都在读取。

You don't need the ACK line. 您不需要ACK线。 Just remove it. 只需将其删除。 Don't send it and don't read it. 不要发送也不阅读。

Because if you have connection side's code like this 因为如果您有这样的连接方代码

    while((Nbytes=input.read(data))!=-1){
        output.write(data,0,Nbytes);
        output.flush();
    }

    // read the ack. and print it
    System.out.println(p.readLine());

You will block on the last line and wait for input. 您将在最后一行上阻止并等待输入。 But since sockets are still open your reading side code 但是由于套接字仍在打开,因此您的阅读端代码

   while((NBytes=SocketInput.read(data))!=-1){ <-- HERE U ARE BLOCKED
        FileOutput.write(data,0,NBytes);
        FileOutput.flush();
    }

will block on while loop condition. 将在while循环条件下阻塞。 Until connection is valid and input is not closed, #read will not return thus you got block. 直到连接有效且输入未关闭, #read才会返回,因此您被阻止了。

Try to close output stream after all the content is transmited 传输完所有内容后,尝试关闭输出流

    while((Nbytes=input.read(data))!=-1){ 
        output.write(data,0,Nbytes);
        output.flush();
    }
    output.close(); // this should unblock blocked thread on the other side
    // read the ack. and print it
    System.out.println(p.readLine());

This should effectively tell the other side that no other data will be transmited (blocked read method will return -1) 这应该有效地告诉另一端,将不会传输其他数据(阻塞的读取方法将返回-1)

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

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