java - 如何将多个客户端连接到单个服务器?

标签 java sockets chat

如何在 Java 中建立多个客户端到单个服务器的连接?这就是到目前为止代码的样子。当我运行该程序时,服务器可以读取客户端的输入,但只能读取一个客户端。当我点击发送消息时也是如此。服务器可以读取它,但该消息不会显示在客户端的显示框中。如何解决这些问题?

服务器线程类

import java.net.*;
import java.io.*;

public class ServerThread extends Thread
{
    private static Thread[] listOfThreads = null;
    private static ServerThread thread = null;
    private Socket connection;
    private PrintWriter output;
    private BufferedReader input;
    private ThreadGroup clientGroup;

public ServerThread(ThreadGroup threadGroup, Socket connection) 
{

    super(threadGroup, "Connection to ChatClient");
    clientGroup = threadGroup;
    this.connection = connection;
    try {       
        output = new PrintWriter(connection.getOutputStream(), true);
        input = new BufferedReader(new InputStreamReader (connection.getInputStream() ));
    }
    catch(IOException e) {
        System.out.println("Error while getting input and output stream from socket");
    }
}   
public void run() {
    try 
    {           
        String data = input.readLine();
        while( data != null ) 
        {

            System.out.println(data);
            int numOfThreads = clientGroup.activeCount();               
                thread.sendToAllClients(data) ;
            clientGroup.enumerate(listOfThreads);                   

            for (int i = 0; i < numOfThreads; i++)
            {               
                ServerThreadThai thread = (ServerThreadThai) listOfThreads[i];                  
                thread.sendToAllClients(data) ;
            }

            data = input.readLine();
        }
    }
    catch(IOException e) {
        System.out.println("Client has been disconnected");
    }
}
public void sendToAllClients(String data) {
    output.println(data);
}
}

聊天服务器

import java.net.*;
import java.io.*;

class ChatServer 
{
public static void main(String[] args)
{
    ServerSocket serverSocket = null;
    ThreadGroup myThreadGroup = new ThreadGroup("Contain chat client threads");
    try
    {       
        serverSocket = new ServerSocket(12);  // Create Server Socket
        System.out.println("Server started. Waitting for client");
        while (true)
        {           
            Socket connectionTo = serverSocket.accept();        
            System.out.println("Received a connection from a client");              
            new ServerThread(myThreadGroup, connectionTo).run();            
        }
    }
    catch (IOException e) {
    System.out.println("Could not use this port");
    System.exit(1);
    }
}
}

聊天客户端

import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class ClientFrame extends JFrame implements ActionListener
{
private PrintWriter output;
private BufferedReader input;
private JButton sendButton, exitButton;
private JTextArea display;
private JTextField dataIn, userName;

public ClientFrame(String host) 
{

    try 
    {       
        Socket socket = new Socket(host, 12);
        input = new BufferedReader( new InputStreamReader(socket.getInputStream()));
        output = new PrintWriter(socket.getOutputStream(), true);       
    }
    catch (UnknownHostException e)
    {
        System.out.println("Unknow host");
        System.exit(1);
    }
    catch(IOException e) 
    {
        System.out.println("Error open connection");
        int width = 500, height = 400;
    }

    Toolkit tk = getToolkit();
    Dimension screen = tk.getScreenSize();
    int width = 500, height = 400;
    setBounds( (screen.width - width)/2, (screen.height - height)/2, width, height);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    dataIn = new JTextField(20);

    userName = new JTextField(5);
    userName.setText("Name");

    sendButton = new JButton("Send text");
    exitButton = new JButton("Exit");

    sendButton.addActionListener(this);
    exitButton.addActionListener(this);

    JPanel p = new JPanel();
    p.setLayout(new FlowLayout());
    p.add(dataIn);
    p.add(sendButton);
    p.add(exitButton);
    p.add(userName);

    display = new JTextArea();
    Container c = getContentPane();
    c.setLayout( new BorderLayout() );

    c.add(display, BorderLayout.CENTER);
    c.add(p, BorderLayout.SOUTH);
    setVisible(true);
}

public void actionPerformed (ActionEvent e) 
{
    JButton src = (JButton) e.getSource();
    if(src == sendButton) 
    { 
        if( dataIn.getText().equals("") ) 
            return;

            output.println(userName.getText() + ": " + dataIn.getText());
            dataIn.setText("");         
            dataIn.requestFocus(true);
    }
    else
    System.exit(0);
}


public void process() 
{ 
    try
    {   
            String data = input.readLine();
            //while (data != null);
            do
            {
                display.append("Welcome");
                data = input.readLine();        
                display.append(data + "\n");
            }
            while (data != null);
    }
    catch(IOException e) 
    {
        System.out.println("Error while reading from server");
    }
}
}

public class ChatClient{
public static void main(String[] args)
{
    String host= "127.0.0.1";       
    ClientFrame client = new ClientFrame(host);
    client.process();


}
}

最佳答案

主要问题是当您收到新的连接请求时,您不会在服务器上启动任何线程。为了生成一个新线程,您需要调用方法 start() 而不是 run()。

尝试更改此行:

 new ServerThread(myThreadGroup, connectionTo).run();  

到这一行:

 new ServerThread(myThreadGroup, connectionTo).start();

不过代码中可能仍然存在其他错误。

关于java - 如何将多个客户端连接到单个服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32660448/

相关文章:

java - 如何让服务器在java中处理其他事情的同时接受新连接

c - 如何确定连接到 C 中的 INADDR_ANY 监听器套接字的客户端使用的 IP

go - 在 golang 中一对一聊天

Javascript + Pubnub 聊天通知

iphone - 通过 Iphone 的视频流

java - javax.xml 和 Xerces 支持的可配置属性的完整列表是什么?

java - 使用正则表达式 java 检索嵌入的 youtube 视频 ID

java - 理解Java中的线程中断

java - 使用 Intellij IDEA 时找不到文件

java - 不要在 API 26+ Android 设备上显示套接字消息