Socket - Software caused connection abort: recv failed [duplicate]

北慕城南 提交于 2020-01-03 03:57:22

问题


I'm trying to build a simple TCP multithreaded client/server application. Whenever a Client (Socket) connects to the ServerSocket and send an Object (Message) that corresponds to the simple serializable class shown below, the server crashes when his ObjectInputStream tries to read from the client Socket getting a SocketExpection.

Message.java

package storageserver;

import java.io.Serializable;

public class Message implements Serializable {

    private static final long serialVersionUID = 27015L;

    public int ClientStatus; // 0 - NotLogged :::  1 - Logged
    public String Command;
    public String[] Commands;  

    public Message()
    {
        this.ClientStatus = 0;
        this.Command = null;
        this.Commands = null;
    }   

    public void createMessage(String msg)
    {
        this.Command = msg;
        this.Commands = msg.split("\\s+");
    }
}

StorageServer.java

package storageserver;
 // imports..


public class StorageServer {

    public static final int MAX_USERS = 250;

    ServerSocket myServerSocket;
    boolean serverOn = true;
    File workingDir;

    public StorageServer(int port, File dir) {

        try {
            InetAddress addr = InetAddress.getByName("192.168.1.73");

            myServerSocket = new ServerSocket(port, MAX_USERS, addr);
            workingDir = dir;
            if(!workingDir.exists())
                workingDir.mkdir();

            System.out.println("StorageServer created successfully.");

        } catch (IOException ex) {
            Logger.getLogger(StorageServer.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Could not create storage server on port 7000. Exiting."); 
            System.exit(-1); 
        }
    }

    public void listen()
    {
        System.out.println("Listening for connections...");
        while(serverOn)
        {
            try {
                //accepts incoming TCP connection
                Socket clientSocket = myServerSocket.accept();

                //starts new service thread to handle client requests in background
                new ClientHandleThread(clientSocket).start();
            }
            catch (IOException e)
            {
                System.out.println("Exception encountered on accept. Ignoring. Stack Trace :"); 
                e.printStackTrace();
            }
        }

        try {
            myServerSocket.close();
        } catch (IOException ex) {
            Logger.getLogger(StorageServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    class ClientHandleThread extends Thread {

        private Socket myClientSocket;
        private HashMap<String, Runnable> commandsMap;
        private Message messageToSend, messageToReceive;

        public ClientHandleThread() {
            super();
        }

        public ClientHandleThread(Socket myClientSocket) {
            this.myClientSocket = myClientSocket;
            this.messageToSend = new Message();
            this.messageToReceive = new Message();
        }

        private void help()
        {
            messageToSend.createMessage("Avaible commands:\n\n"
                + "exit                       -> Exits the App\n"
                + "stop                       -> Stops the server\n"
                + "dir                        -> Gets personal file's info in current server\n");
            messageToSend.ClientStatus = 0;
        }

        @Override
        public void run()
        {
            ObjectInputStream in = null; 
            ObjectOutputStream out = null;

            System.out.println("Accepted connection from "
                        +  myClientSocket.getInetAddress().getHostAddress()+ ":" + myClientSocket.getPort());

            try
            {        
                System.out.println("IN..");
                in = new ObjectInputStream(myClientSocket.getInputStream()); 
                out = new ObjectOutputStream(myClientSocket.getOutputStream()); 
                System.out.println("IN!");

                messageToReceive = (Message) in.readObject(); //exception here - Software caused connection abort: recv failed
                System.out.println("Client Says :" + messageToReceive.Command);

                out.writeObject(messageToSend);
                out.flush(); 

            } catch (IOException | ClassNotFoundException ex) {
                ex.printStackTrace();
                Logger.getLogger(StorageServer.class.getName()).log(Level.SEVERE, null, ex);
            }
            finally
            {
                try
                {                    
                    in.close(); 
                    out.close(); 
                    myClientSocket.close(); 
                    System.out.println("...Stopped"); 
                } 
                catch(IOException e) 
                { 
                    e.printStackTrace(); 
                }
            }
        }

    }

}

Debug output

java.net.SocketException: Software caused connection abort: recv failed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.net.SocketInputStream.read(SocketInputStream.java:223)
    at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2303)
    at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2596)
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2606)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1319)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
    at storageserver.StorageServer$ClientHandleThread.run(StorageServer.java:145)
nov 11, 2015 2:53:36 AM storageserver.StorageServer$ClientHandleThread run

What may be causing this exception ? I'm sure i do not close or reset the socket connection anywhere (client/server side).

EDIT:

Added client code below. Client gets an exception when trying to receive() a response from the server.

TCPService.java (Client)

package client;

//imports..

public class TCPService {

    private Socket clientSocket;


    public TCPService(String host, int port)
    {
        try {
            clientSocket = new Socket(InetAddress.getByName(host), port);
            clientSocket.setSoTimeout(5000);
        } catch (IOException ex) {
            System.err.println("Cant connect to Storage Server.\n" + ex);
            System.exit(-1);
        }

    }

    public Message receive()
    {
        try { 
            ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
            try {
                Message msg = (Message) in.readObject();

                if(msg instanceof Message)
                    return msg;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }      

        }   catch (IOException ex) {
            Logger.getLogger(TCPService.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public void send(Message msg)
    {
        try {
            ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
            oos.writeObject(msg);
            oos.flush();
            oos.close();
        } catch (IOException ex) {
            Logger.getLogger(TCPService.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    //Main
     public static void main(String[] args) throws IOException
    {        
        /* Service Variable Declaration */
        TCPService tcpService = new TCPService(args[0], args[1]);

        /* Other Variables */
        String buf = "";
        Scanner scanIn = new Scanner(System.in);
        Message msg = new Message();
        isTCPRunning = true;

        /* While-Loop for TCP Service */
        while (isTCPRunning)
        {
            System.out.print("[User@StorageServer] Insert command: ");
            buf = scanIn.nextLine();

            msg.createMessage(buf);

            scanIn.reset();

            tcpService.send(msg);

            msg = tcpService.receive(); //SocketException -> Socket Closed

            System.out.println("[StorageServer] " + msg.Command);

            tcpService.handleMessage(msg);
        }
}

回答1:


Immediately upon sending a message, the client closes the ObjectOutputStream. This closes the socket's output stream, which closes the socket. By the time the client tries to read from the input stream, the socket is already closed, thus the exception on the client side. This may also be causing the problem on the server side, since by the time the server is reading data, the TCP connection may have been closed.



来源:https://stackoverflow.com/questions/33643652/socket-software-caused-connection-abort-recv-failed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!