代码之家  ›  专栏  ›  技术社区  ›  Imma Paul Becotte

(客户端-服务器)当服务器的serversocket接受客户端不工作时的Java控件[closed]

  •  -1
  • Imma Paul Becotte  · 技术社区  · 11 年前

    我目前正在学习套接字,我的作业是创建一个聊天室,让多个客户可以自由交谈。老师给出的提示是,聊天室服务器仅在客户端尝试发送消息时接受客户端。这个作业应该在不使用线程的情况下完成。

    根据给出的提示,我尝试在客户端和服务器代码中创建未绑定的ServerSocket和Socket。关键思想是,当客户端尝试向服务器发送消息时,客户端代码将连接未绑定的套接字,然后将触发服务器连接未绑定服务器套接字并接受客户端。

    然而,当我运行代码时,服务器和客户端代码都在运行,它们声称所有连接都已建立,但我根本无法在客户端和服务器之间传输消息。

    我尝试过在网上寻找答案,但找不到答案。我想问一下,我决定服务器何时接受客户端的方式是否正确。

    我的聊天室服务器:

    public class ChatRoom {
        public static void main(String[] args) throws Exception {
    
            int portNum = 4321;
    
            ServerSocket serverSocket = new ServerSocket();
    
            int count = 1;
    
            while (true) {
    
                // redeclare everything each round
                Socket socket = null;
                PrintWriter out = null;
                BufferedReader in = null;
                BufferedReader stdIn = null;
                String inputLine = null;
    
                // accept each time round
                serverSocket.bind(new InetSocketAddress(portNum));
                socket = serverSocket.accept();
                System.out.println("newly accepted!");
    
                out = new PrintWriter(socket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                stdIn = new BufferedReader(new InputStreamReader(System.in));
    
                if (!((inputLine = in.readLine()).equals("Bye"))) {
                    System.out.println("Client says: " + inputLine);
                    out.println(stdIn.readLine());
                    out.flush();
    
                    System.out.println("Message Count: " + count);
                    count++;
                }
                else {
                    out.println(inputLine);
                    serverSocket.close();
                    socket.close();
                    out.close();
                    in.close();
                }
            }
        }   
    }
    

    我的聊天室客户:

    public class ChatRoomClient {
        public static void main(String[] args) throws Exception {
            String hostName = "localhost";
            int portNumber = 4321;
    
            Socket echoSocket = new Socket();   // creates an unbound socket
    
            PrintWriter out = null;
            BufferedReader in = null;
            BufferedReader stdIn = null;
    
            String userInput;
            do {
                out = null;
                in = null;
                stdIn = null;
    
                // each time round the unbound socket attempts to connect to send a message
                echoSocket.connect(new InetSocketAddress(hostName, portNumber));
                System.out.println("successfully connected");
                out = new PrintWriter(echoSocket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
                stdIn = new BufferedReader(new InputStreamReader(System.in));
    
                userInput = stdIn.readLine();
                out.flush();
                System.out.println("Server says: " + in.readLine());
            }
            while (!userInput.equals("Bye"));
    
            // close everything
            echoSocket.close();
            in.close();
            stdIn.close();
        }
    }
    

    谢谢

    3 回复  |  直到 11 年前
        1
  •  0
  •   user207421    11 年前

    老师给出的提示是,聊天室服务器仅在客户端尝试发送消息时接受客户端。这个作业应该在不使用线程的情况下完成。

    老师给出的暗示没有道理。客户端必须连接,然后服务器接受。客户端在未首先连接的情况下无法发送消息。也许老师的意思是客户在有东西要发送之前不应该连接?

    根据给出的提示,我尝试在客户端和服务器代码中创建未绑定的ServerSocket和Socket。关键思想是,当客户端尝试向服务器发送消息时,客户端代码将连接未绑定的套接字,然后将触发服务器连接未绑定服务器套接字并接受客户端。

    但这不会发生。这是不可能的。如果您尝试连接到未侦听的端口,将获得 ConnectException. 将端口置于侦听状态的唯一方法是绑定 ServerSocket. 没有神奇的后门,服务器可以通过它知道客户端想要连接,所以现在应该进行绑定。

    这个作业应该在不使用线程的情况下完成。

    无法以这种方式“创建一个聊天室,让多个客户可以自由交谈”,除非您希望使用非阻塞I/O或滥用 available() 设施,或对每条消息使用连接,但我看不到如何将一个客户端的消息传递给其他客户端,除非允许您对它们进行批处理。

    正如你所描述的,这项任务有太多无法估量的方面。提出的问题实际上没有意义,你提出的解决方案当然没有意义。你应该继续以正常的方式编写程序,包括连接、接受和一些I/O。当你的老师提出澄清时,让它发挥作用。

        2
  •  0
  •   TA Nguyen    11 年前

    啊。。。如果不为服务器使用线程,您将无法为多个客户端提供服务。无论如何,您当前的代码有问题,您的逻辑不正确。

    • 您的stdIn应该在循环外部声明和实例化,您不需要继续为每个循环创建stdIn对象。
    • 你的“in”套接字accept()和echoSocket.connect()也应该在循环之外,这就是为什么你没有从服务器得到任何答案,因为你没有在同一条线上收听。就像你的手机一样,每次都要用闪光灯拨打新号码。都指向同一个服务器,但连接不同。

    因此,我们的想法是在服务器和客户端之间建立一个可以双向通信的连接(通过输入和输出流)。然后,您可以从客户端开始循环和对话,然后服务器接收,然后服务器对话,然后客户端接收,然后客户端对话。。。。直到客户说再见。。。

    更多信息: http://ta.cnci.org/basicirc

        3
  •  0
  •   Imma Paul Becotte    11 年前

    虽然我想更新,但我设法在不使用线程的情况下解决了我的问题。只是插座哈哈。我想把我的答案张贴出来以供参考。。

    我的聊天室服务器:

    public class ChatRoomServer {
        public static void main(String[] args) throws Exception {
    
            ServerSocket serverSocket = new ServerSocket(4321);
    
            while(true) {
                Socket clientSocket = serverSocket.accept();
    
                BufferedReader in = new BufferedReader
                             (new InputStreamReader(clientSocket.getInputStream()));
    
                String inputLine = in.readLine();
    
                System.out.println("Client says: " + inputLine);
    
                in.close();
                clientSocket.close();
    
            }       
    
        }   
    }
    

    我的聊天室客户:

    public class ChatRoomClient {
        public static void main(String[] args) throws Exception {
    
            String hostName = "localhost";
            int portNum = 4321;
    
            BufferedReader stdIn = new BufferedReader
                                       (new InputStreamReader(System.in));
    
            while (true) {
    
                String userInput;
    
                userInput = stdIn.readLine();
    
                Socket echoSocket = new Socket(hostName, portNum);
    
                PrintWriter out = new PrintWriter
                                          (echoSocket.getOutputStream(), true);
    
                out.println(userInput);
                out.flush();
    
                out.close();
                echoSocket.close();
    
                if (userInput.equals("Bye")) {
                    stdIn.close();
                    break;
                }
            }
    
        }
    }