【问题标题】:""Connection reset"" error after connected to second client in instant messaging application在即时消息应用程序中连接到第二个客户端后出现“连接重置”错误
【发布时间】:2015-01-08 17:01:24
【问题描述】:

好像连接第二个客户端后连接被重置了

这是第一个客户,我已经评论了大部分内容以使更清晰

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

    }

这是第二个客户端,98% 与第一个相同

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

这是服务器端,位于两个客户端之间,发送和接收消息

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

    }

据我了解,在两个客户端都连接后,连接并没有保持活动状态,我已经读到连接不应该在被告知之前关闭。我不知道是什么让它自己关闭了。

我收到的错误是在客户端两个代码的第 101 行,这意味着在创建流后连接已关闭。

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

【问题讨论】:

  • 请发布服务器主方法,可能服务器在客户端传输数据之前终止。
  • @rafalopez79 完成编辑

标签: java input stream output serversocket


【解决方案1】:

服务器执行 StartServer() 并终止,关闭套接字:

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

我认为您缺少调用 ReceiveMessage() 方法,也许它应该在调用 SetupStreams() 后在 StartServer() 中完成:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 2022-01-24
    • 2013-10-20
    • 2015-05-19
    • 1970-01-01
    • 2019-01-06
    • 2020-11-18
    相关资源
    最近更新 更多