【问题标题】:java socket connection resetjava socket连接重置
【发布时间】:2017-02-20 20:54:26
【问题描述】:

我正在尝试制作简单的服务器客户端应用程序,让客户端向服务器发送文件,然后服务器发送确认消息,表明它收到了文件

这是服务器类。

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

}

当我运行服务器和客户端时我得到了什么错了,有什么问题?

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    你陷入了僵局。客户端正在将套接字读取到流的末尾,而您还没有关闭套接字,因此没有流的结尾,所以当您读取 ACK 行时,双方都在读取。

    您不需要 ACK 行。只需将其删除。请勿发送,请勿阅读。

    【讨论】:

    • 我在客户端类 System.out.println(p.readLine());其中 p 是缓冲阅读器
    • 您在服务器仍在等待自己的read() 中的流结束时读取了 ACK 行。
    【解决方案2】:

    因为如果你有这样的连接端代码

        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)

    【讨论】:

    • 关闭输出流会关闭套接字,所以下面的readLine()会得到一个“套接字关闭”异常。
    猜你喜欢
    • 2014-01-21
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 2014-02-15
    相关资源
    最近更新 更多