如何使用套接字将数据从服务器发送到多个客户端?
How to send data from Server to multiple Clients using Sockets?
我有简单的服务器-客户端程序:
public class Server extends Thread {
private ServerSocket server;
public Server(int port) {
try {
this.server = new ServerSocket(port);
System.out.println("New server initialized!");
this.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Socket client = server.accept();
System.out.println(client.getInetAddress().getHostName()
+ " connected");
new ServerHandler(client);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
服务器处理程序必须在流中发送消息:
public class ServerHandler extends Thread {
protected Socket client;
protected String userInput;
protected PrintWriter out;
protected BufferedReader console;
public ServerHandler(Socket client) {
this.client = client;
this.userInput = null;
this.start();
}
public void run() {
System.out.println("New Communication Thread Started");
System.out.println("Enter message:");
try {
this.out = new PrintWriter(client.getOutputStream(), true);
this.console = new BufferedReader(new InputStreamReader(System.in));
while ((this.userInput = console.readLine()) != null) {
this.out.println(userInput);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端收到该消息:
public class Client {
protected Socket client;
protected BufferedReader in;
public Client(String hostName, int ip) {
try {
this.client = new Socket(hostName, ip);
this.in = new BufferedReader(new InputStreamReader(
this.client.getInputStream()));
String buffer = null;
while ((buffer = in.readLine()) != null) {
System.out.println(buffer);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
它在一个客户端上运行良好,但是当我启动新的客户端时,出现了从服务器接收消息的问题。
我做错了什么?
我找到了答案:
public class Server extends Thread {
private ServerSocket server;
protected List<ClientHandler> clients;
public Server(int port) {
try {
this.server = new ServerSocket(port);
System.out.println("New server initialized!");
clients = Collections
.synchronizedList(new ArrayList<ClientHandler>());
this.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Socket client = server.accept();
System.out.println(client.getInetAddress().getHostName()
+ " connected");
ClientHandler newClient = new ClientHandler(client);
clients.add(newClient);
new SendMessage(clients);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
ClientHandler 而不是 Serverhandler class:
public class ClientHandler {
protected Socket client;
protected PrintWriter out;
public ClientHandler(Socket client) {
this.client = client;
try {
this.out = new PrintWriter(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
可以将线程添加到客户端 class 但在没有 it.I 假设的情况下工作正常,因为当调用 main 方法时自动创建新线程:
public class Client {
protected Socket client;
protected BufferedReader in;
public Client(String hostName, int ip) {
try {
this.client = new Socket(hostName, ip);
this.in = new BufferedReader(new InputStreamReader(
this.client.getInputStream()));
String buffer = null;
while ((buffer = in.readLine()) != null) {
System.out.println(buffer);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Class 向客户端发送数据:
public class SendMessage extends Thread {
protected List<ClientHandler> clients;
protected String userInput;
protected BufferedReader console;
public SendMessage(List<ClientHandler> clients) {
this.clients = clients;
this.userInput = null;
this.start();
}
public void run() {
System.out.println("New Communication Thread Started");
if (clients.size() == 1) {
System.out.println("Enter message:");
}
try {
if (clients.size() > 0) {
this.console = new BufferedReader(new InputStreamReader(
System.in));
while ((this.userInput = console.readLine()) != null) {
if (userInput != null & userInput.length() > 0) {
for (ClientHandler client : clients) {
client.out.println(userInput);
client.out.flush();
Thread.currentThread();
Thread.sleep(1 * 1000);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
现在可以了!
刷新数据后需要让 SendMessage 线程休眠。
主要用于服务器启动器:
public static void main(String[] args) {
new Server(1200);
}
客户端启动器的主要内容:
public static void main(String[] args) {
new Client("127.233.0.1", 1200);
}
我有简单的服务器-客户端程序:
public class Server extends Thread {
private ServerSocket server;
public Server(int port) {
try {
this.server = new ServerSocket(port);
System.out.println("New server initialized!");
this.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Socket client = server.accept();
System.out.println(client.getInetAddress().getHostName()
+ " connected");
new ServerHandler(client);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
服务器处理程序必须在流中发送消息:
public class ServerHandler extends Thread {
protected Socket client;
protected String userInput;
protected PrintWriter out;
protected BufferedReader console;
public ServerHandler(Socket client) {
this.client = client;
this.userInput = null;
this.start();
}
public void run() {
System.out.println("New Communication Thread Started");
System.out.println("Enter message:");
try {
this.out = new PrintWriter(client.getOutputStream(), true);
this.console = new BufferedReader(new InputStreamReader(System.in));
while ((this.userInput = console.readLine()) != null) {
this.out.println(userInput);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端收到该消息:
public class Client {
protected Socket client;
protected BufferedReader in;
public Client(String hostName, int ip) {
try {
this.client = new Socket(hostName, ip);
this.in = new BufferedReader(new InputStreamReader(
this.client.getInputStream()));
String buffer = null;
while ((buffer = in.readLine()) != null) {
System.out.println(buffer);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
它在一个客户端上运行良好,但是当我启动新的客户端时,出现了从服务器接收消息的问题。 我做错了什么?
我找到了答案:
public class Server extends Thread {
private ServerSocket server;
protected List<ClientHandler> clients;
public Server(int port) {
try {
this.server = new ServerSocket(port);
System.out.println("New server initialized!");
clients = Collections
.synchronizedList(new ArrayList<ClientHandler>());
this.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Socket client = server.accept();
System.out.println(client.getInetAddress().getHostName()
+ " connected");
ClientHandler newClient = new ClientHandler(client);
clients.add(newClient);
new SendMessage(clients);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
ClientHandler 而不是 Serverhandler class:
public class ClientHandler {
protected Socket client;
protected PrintWriter out;
public ClientHandler(Socket client) {
this.client = client;
try {
this.out = new PrintWriter(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
可以将线程添加到客户端 class 但在没有 it.I 假设的情况下工作正常,因为当调用 main 方法时自动创建新线程:
public class Client {
protected Socket client;
protected BufferedReader in;
public Client(String hostName, int ip) {
try {
this.client = new Socket(hostName, ip);
this.in = new BufferedReader(new InputStreamReader(
this.client.getInputStream()));
String buffer = null;
while ((buffer = in.readLine()) != null) {
System.out.println(buffer);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Class 向客户端发送数据:
public class SendMessage extends Thread {
protected List<ClientHandler> clients;
protected String userInput;
protected BufferedReader console;
public SendMessage(List<ClientHandler> clients) {
this.clients = clients;
this.userInput = null;
this.start();
}
public void run() {
System.out.println("New Communication Thread Started");
if (clients.size() == 1) {
System.out.println("Enter message:");
}
try {
if (clients.size() > 0) {
this.console = new BufferedReader(new InputStreamReader(
System.in));
while ((this.userInput = console.readLine()) != null) {
if (userInput != null & userInput.length() > 0) {
for (ClientHandler client : clients) {
client.out.println(userInput);
client.out.flush();
Thread.currentThread();
Thread.sleep(1 * 1000);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
现在可以了! 刷新数据后需要让 SendMessage 线程休眠。 主要用于服务器启动器:
public static void main(String[] args) {
new Server(1200);
}
客户端启动器的主要内容:
public static void main(String[] args) {
new Client("127.233.0.1", 1200);
}