簡體   English   中英

Java套接字連接重置

[英]java socket connection reset

我正在嘗試制作一個簡單的服務器客戶端應用程序,該應用程序允許客戶端將文件發送到服務器,然后服務器發送確認消息,表示已收到文件

這是服務器類。

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類

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

客戶類

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

}

運行服務器和客戶端時得到的結果是什么,如果停止客戶端,則控制台異常連接重置中的服務器應用程序類型會消失,但是如果我刪除了確認部分,那么文件將被接收並且沒有任何問題,這是什么是問題嗎?

你陷入僵局。 客戶端正在讀取套接字到流的末尾,並且您沒有關閉套接字,因此沒有流的末尾,因此當您讀取ACK線時,兩個對等方都在讀取。

您不需要ACK線。 只需將其刪除。 不要發送也不閱讀。

因為如果您有這樣的連接方代碼

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

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

您將在最后一行上阻止並等待輸入。 但是由於套接字仍在打開,因此您的閱讀端代碼

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

將在while循環條件下阻塞。 直到連接有效且輸入未關閉, #read才會返回,因此您被阻止了。

傳輸完所有內容后,嘗試關閉輸出流

    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());

這應該有效地告訴另一端,將不會傳輸其他數據(阻塞的讀取方法將返回-1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM