简体   繁体   中英

“”Connection reset“” error after connected to second client in instant messaging application

It seems like the connection is reset after the second client is connected

This is the first client, I have commented most of the line to make is clearer

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;

    import javax.swing.JFrame;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;


    public class ClientOneGui extends JFrame {

        private static final long serialVersionUID = 1L;
        JTextField userInput = new JTextField();
        JTextArea chatHistory = new JTextArea();

        Socket cS; // Socket to connect to Server
        ObjectOutputStream output; // To send messages to server, server sends to clientTwo(another client)
        ObjectInputStream input; // To receive messages from server, message sent to server from clientTwo(another client)

        String message;// Variable to hold messages sent from server, which is from another client

        //Constructor
        public ClientOneGui() {
            super("ClientOne"); //Window Title
            add(userInput, BorderLayout.SOUTH); // add TextField for user input
            add(chatHistory); // add TextArea for chat history

            // Detects enter pressed by user inside the TextField 
            // then run the SendMessage method
            userInput.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        SendMessage(e.getActionCommand());
                        userInput.setText("");
                    }
                }
            );

            //Housekeeping stuff
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
            this.setLocationRelativeTo(null);
            this.setSize(300, 400);
        }

        //This is the only method called in the main class, after the constructor
        //this method runs the other three methods inside it
        public void StartClient() {
                ConnectToServer();
                SetupStreams();
                ReceiveMessage();
        }

        //Connect to server
        public void ConnectToServer() {
            try{
                appendString("Waiting for connection"); // appendString method is created down below
                cS = new Socket("127.0.0.1",45678);
                appendString("Connected to server!");
            } catch(IOException e) {
                System.out.println("ConnectToServer method");
            }
        }

        //Setup output and input streams
        public void SetupStreams() {
            try {
                output = new ObjectOutputStream(cS.getOutputStream());
                output.flush();
                input = new ObjectInputStream(cS.getInputStream());
                appendString("Start chatting!");
            } catch (IOException e) {
                System.out.println("SetupStreams ClientOne Method");
            }
        }

        //Send message when enter is pressed
        public void SendMessage(String str) {
            try {
                output.writeObject(str); // Write message to server
                appendString(str);
            } catch (IOException e) {
                System.out.println("SendMessage ClientOne Method");
            }   
        }

        //Keep receiving message while connected
        public void ReceiveMessage() {
            do{
                try {
                    message = (String) input.readObject(); // Read the message from server
                    appendString(message);
                } catch (IOException | ClassNotFoundException e) {
                    System.out.println("Client One connection lost");
                }
            }while(cS.isConnected());
        }

        //Add text to chatHistory
        public void appendString(final String string) {
            SwingUtilities.invokeLater(new Runnable(){
                public void run() {
                    chatHistory.append(">"+string+"\n");
                }
            });
        }

    }

This is the second client, 98% identical to the first one

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;

    import javax.swing.JFrame;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;

    public class ClientTwoGui extends JFrame {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        JTextField userInput = new JTextField();
        JTextArea chatHistory = new JTextArea();

        Socket cS; // Socket to connect to Server
        ObjectOutputStream output; // To send messages to server, server sends to clientOne(another client)
        ObjectInputStream input; // To receive messages from server, message sent to server from clientOne(another client)

        String message; // Variable to hold messages sent from server, which is from another client

        //Constructor
        public ClientTwoGui() {
            super("ClientTwo"); //Window Title
            add(userInput, BorderLayout.SOUTH); // add TextField for user input
            add(chatHistory); // add TextArea for chat history

            // Detects enter pressed by user inside the TextField 
            // then run the SendMessage method
            userInput.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        SendMessage(e.getActionCommand());
                        userInput.setText("");
                    }
                }
            );

            //Housekeeping stuff
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
            this.setLocationRelativeTo(null);
            this.setSize(300, 400);
        }

        //This is the only method called in the main class, after the constructor
        //this method runs the other three methods inside it
        public void StartClient() {
            ConnectToServer();
            SetupStreams();
            ReceiveMessage();
        }

        //Connect to server
        public void ConnectToServer() {
            try{
                appendString("Waiting for connection");
                cS = new Socket("127.0.0.1",45678);
                appendString("Connected to server!");
            } catch(IOException e) {
                e.printStackTrace();
            }
        }

        //Setup output and input streams
        public void SetupStreams() {
            try {
                output = new ObjectOutputStream(cS.getOutputStream());
                output.flush();
                input = new ObjectInputStream(cS.getInputStream());
                appendString("Start chatting!");
            } catch (IOException e) {
                System.out.println("SetupStreams ClientTwo Method");
            }
        }

        //Send message when enter is pressed
        public void SendMessage(String str) {
            try {
                output.writeObject(str); // Write message to server
                appendString(str);
            } catch (IOException e) {
                System.out.println("SendMessage ClientTwo Method");
            }
        }

        //Keep receiving message while connected
        public void ReceiveMessage() {
            do{
                try {
                    message = (String) input.readObject(); // Read the message from server
                    appendString(message);
                } catch (IOException | ClassNotFoundException e) {
//=====================================================================================
                    System.out.println("Client Two connection lost"); // <<<<<Error
//=====================================================================================             
                }
            }while(cS.isConnected());
        }

        //Append string to chatHistory
        public void appendString(final String string) {
            SwingUtilities.invokeLater(new Runnable(){
                public void run() {
                    chatHistory.append(">"+string+"\n");
                }
            });
        }
    }

This is the server side, which sits in between the two clients, sends and receive messages

    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;

    public class TheServer {

        //One server socket, two client sockets
        ServerSocket sS;
        Socket cSOne;
        Socket cSTwo;

        //The streams
        ObjectOutputStream outputOne; //input Stream for first client
        ObjectInputStream inputOne; //output Stream for first client
        ObjectOutputStream outputTwo; //input Stream for second client
        ObjectInputStream inputTwo;//output Stream for second client

        //The messages
        String messageOne; // messages from client one
        String messageTwo; // messages from client two

        //This is the only method called
        public void StartServer() {
            System.out.println("Server Started");
            try {
                        sS = new ServerSocket(45678);
                        WaitForClient();
                        SetupStreams();
            } catch (IOException e) {
                System.out.println("StartServer Method " + e);
            }
        }

        //Connect to client
        public void WaitForClient() {
            try{
                cSOne = sS.accept();
                System.out.println("Connected to client one");
                cSTwo = sS.accept();
                System.out.println("Connected to client Two");
            } catch(IOException e) {
                System.out.println("WaitForClient Method");
            }
        }

        //Setup output and input streams
        public void SetupStreams() {
            try {
                outputOne = new ObjectOutputStream(cSOne.getOutputStream());
                outputOne.flush();
                inputOne = new ObjectInputStream(cSOne.getInputStream());
                System.out.println("Client One streams setup");

                outputTwo = new ObjectOutputStream(cSTwo.getOutputStream());
                outputTwo.flush();
                inputTwo = new ObjectInputStream(cSTwo.getInputStream());

                System.out.println("Client Two streams setup");
            } catch (IOException e) {
                System.out.println("SetupStreams Method");
            }
        }

        //Keep receiving messages while both clients are connected
        public void ReceiveMessage() {
            do{
                try {
                    messageOne = (String)inputOne.readObject();
                    messageTwo = (String)inputTwo.readObject();
                    outputTwo.writeObject(messageOne);
                    System.out.println(messageOne);
                    outputOne.writeObject(messageTwo);
                    System.out.println(messageTwo);
                } catch (ClassNotFoundException | IOException e) {
                    System.out.println("SendReceiveMessage Method " + e);
                }
            }while(!messageOne.equals(null)||!messageTwo.equals(null));
        }

        //Keep sending messages while both clients are connected
        public void SendMessage() {
            do{
                try {
                    outputTwo.writeObject(messageOne);
                    System.out.println(messageOne);
                    outputOne.writeObject(messageTwo);
                    System.out.println(messageTwo);
                } catch (IOException e) {
                    System.out.println("SendReceiveMessage Method " + e);
                }
            }while(!messageOne.equals(null)||!messageTwo.equals(null));
        }

    }

From what I understand, the connection didn't kept alive after both clients are connected, I have read that the connections aren't suppose to be closed until they are told to. I don't know what makes it closed by itself.

The error I received is at line 101 in client two codes, meaning the connection is closed after the streams are created.

public class ServerMain {
    public static void main(String[] args) {
        TheServer sc = new TheServer);
        sc.StartServer();
    }
}

Server executes StartServer() and terminates, closing the sockets:

public void StartServer() {
        System.out.println("Server Started");
        try {
                    sS = new ServerSocket(45678);
                    WaitForClient();
                    SetupStreams();
        } catch (IOException e) {
            System.out.println("StartServer Method " + e);
        }
    }

I think you are missing to call ReceiveMessage() method, perhaps it should be done in StartServer() after calling to SetupStreams() :

public void StartServer() {
        System.out.println("Server Started");
        try {
                    sS = new ServerSocket(45678);
                    WaitForClient();
                    SetupStreams();
                    ReceiveMessage();
        } catch (IOException e) {
            System.out.println("StartServer Method " + e);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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