Java (客户机-服务器)当服务器';服务器套接字接受客户端不工作

Java (客户机-服务器)当服务器';服务器套接字接受客户端不工作,java,sockets,client-server,serversocket,Java,Sockets,Client Server,Serversocket,我目前正在学习套接字,我的家庭作业是创建一个聊天室,让多个客户可以自由交谈。老师给出的提示是,聊天室服务器仅在客户端尝试发送消息时才接受客户端。这个作业应该不用线程来完成 根据给出的提示,我尝试在客户端和服务器代码中创建未绑定的ServerSocket和Socket。关键思想是,当客户端尝试向服务器发送消息时,客户端代码将连接未绑定的套接字,然后触发服务器连接未绑定的ServerSocket并接受客户端 但是,当我运行代码时,服务器和客户机代码都在运行,他们声称所有连接都已建立,但我根本无法在客

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

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

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

我试着在网上找到答案,但找不到任何答案。我想问一下,我决定服务器何时接受客户机的方法是否正确

我的聊天室服务器:

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

谢谢

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

  • 您的stdIn应该在循环之外声明和实例化,您不需要为每个循环持续创建stdIn对象
  • 您的“in”socket accept()和echoSocket.connect()也应该在循环之外,这就是为什么您没有从服务器获得任何答案,因为您没有在同一行上侦听。就像你的手机一样,每次都用闪光灯拨新号码。都指向同一台服务器,但它是不同的连接
所以,我们的想法是在服务器和客户端之间建立一个连接(单一连接),它可以双向通信(通过输入和输出流)。然后您可以循环和对话,从客户机开始,然后是服务器接收,然后是服务器对话,然后是客户机接收,然后是客户机对话。。。。直到客户说再见

更多信息:

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

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

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

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

这个作业应该不用线程来完成

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


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

我想更新,但我设法解决了我的问题,没有使用线程。哈哈。我想把我的答案贴出来作为参考会很好

我的聊天室服务器:

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

    }
}

代码中有很多错误/没有太多意义的地方。也许这是一个很好的开始。谢谢!这是一个很好的教程,我会看一遍。但是,是否可以不使用线程来执行此操作?@Imma线程是迄今为止最方便的方法。不使用线程也可以这样做。如果您一次有数百个连接,您将遇到线程的性能问题,必须以另一种方式进行,但是如果您没有很多连接,请使用线程。谢谢!我想我对hahaThis是一个聊天系统这个问题有一些误解?“多个客户可以自由交谈”的地方?不是。是的,这是一个在控制台上运行的聊天系统。我不认为这是一个实际的聊天系统,因为我被告知要多次运行客户机文件来模拟连接到服务器的多个客户机