在客户端服务器套接字程序中,当客户端套接字未读取输入流时出现套接字异常

In Client server socket program, getting socket exception when input stream is not read by clientsocket

在下面的客户端-服务器套接字程序中,客户端正在向监听端口 3500 的服务器发送数据,但这里服务器没有向客户端发送任何数据,所以在客户端套接字程序中,我这样做未从输入流中读取然后出现套接字异常、套接字写入错误。 以下是服务器代码:

    private static ServerSocket sc = null;

    private static final int port = 3500;

    public static void main(String args[]) throws IOException{
        try {
             sc = new ServerSocket(port);
             while(true){   
                Socket socket = sc.accept();
                System.out.println("Listening on port <=> "+port);
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                String message = (String) ois.readObject();
                System.out.println("Received Request <=>"+message);
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                oos.writeObject("Hi Client received your message<=>"+message);
                ois.close();
                oos.close();
                socket.close();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

客户端套接字代码如下:

try {

            ObjectOutputStream oos = null;
            ObjectInputStream ois = null;
            Socket clientsocket = null;

            for(int i=0;i<2;i++){
            clientsocket = new Socket(InetAddress.getLocalHost().getHostName(), 3500);
            oos = new ObjectOutputStream(clientsocket.getOutputStream());
            oos.writeObject("Client Request: "+i);
            //ois = new ObjectInputStream(clientsocket.getInputStream());
            //String message = (String) ois.readObject();
            //System.out.println("Message sent by Server: " + message);
            //ois.close();
            oos.close();    
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

在上面的代码中,如果删除了注释,则代码可以正常工作,但会混淆为什么在没有数据可读的情况下要读取输入流。

按照上面的方法注释输入流部分后出现以下异常。

Listening on port <=> 3500
Received Request <=>Client Request: 0
java.net.SocketException: Software caused connection abort: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(Unknown Source)
    at java.net.SocketOutputStream.write(Unknown Source)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
    at java.io.ObjectOutputStream.writeNonProxyDesc(Unknown Source)
    at java.io.ObjectOutputStream.writeClassDesc(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeFatalException(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at com.springexercise.demo.ServerTest.main(ServerTest.java:28)

错误是因为您在服务器有机会向流中写入数据之前关闭了客户端的连接。

如果删除

ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi Client received your message<=>"+message);
....
oos.close();

部分错误应该得到解决,因为服务器不再尝试在关闭的连接上写入。

如果您在代码中有客户端读取部分,则整个过程都有效,因为客户端等待连接中的新数据。这导致当服务器尝试写入时连接仍然打开并且一切都按预期从 java 站点工作的情况。