如何在java客户机-服务器程序中向多个客户机发送消息
多个客户端(A、B、C、D等)通过同一个套接字连接到一台服务器。它们都会在需要时向服务器发送消息。客户端消息只发送到服务器(而不发送到其他客户端)。但每当服务器发送消息时,都应该将其传递给所有客户端。请帮助我解决仅能在1台客户端上获取服务器消息的堵塞 //多线程服务器.java如何在java客户机-服务器程序中向多个客户机发送消息,java,netbeans,client-server,Java,Netbeans,Client Server,多个客户端(A、B、C、D等)通过同一个套接字连接到一台服务器。它们都会在需要时向服务器发送消息。客户端消息只发送到服务器(而不发送到其他客户端)。但每当服务器发送消息时,都应该将其传递给所有客户端。请帮助我解决仅能在1台客户端上获取服务器消息的堵塞 //多线程服务器.java package server; import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.Vector; pub
package server;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Vector;
public class MultithreadedServer
{
Vector<ClientHandler> clients = new Vector<ClientHandler>();
Vector<String> users = new Vector<String>();
private static ServerSocket servSocket;
private static final int PORT = 1247;
public MultithreadedServer() throws IOException{
servSocket = new ServerSocket(PORT);
while(true) {
Socket client = servSocket.accept();
System.out.println("\nNew client accepted.\n");
ClientHandler handler;
handler = new ClientHandler(client);
clients.add(handler);
}
}
public static void main(String[] args) throws IOException
{
MultithreadedServer ms = new MultithreadedServer();
}
class ClientHandler extends Thread
{
private Socket client;
private BufferedReader in;
private PrintWriter out;
String name,message,response;
public ClientHandler(Socket socket)
{
//Set up reference to associated socket...
client = socket;
try
{
in = new BufferedReader(
new InputStreamReader(
client.getInputStream()));
out = new PrintWriter(
client.getOutputStream(),true);
}
catch(IOException e)
{
e.printStackTrace();
}
start();
}
public void sendMessage(String msg) {
System.out.println("is it even coming here?");
out.println("Server:" + msg);
}
public void boradcast(String message) {
// send message to all connected users
for (ClientHandler c : clients) {
c.out.println("Server: hello");
}
}
public String getUserName() {
return name;
}
public void run()
{
try
{
String received;
do
{ System.out.println("Enter Your Message: ");
String msg = in.readLine();
out.println(msg);
boradcast("testing");
received = in.readLine();
out.println("ECHO: " + received);
//Repeat above until 'QUIT' sent by client...
}while (!received.equals("QUIT"));
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (client!=null)
{
System.out.println(
"Closing down connection...");
client.close();
}
}catch(IOException e)
{
e.printStackTrace();
}
}
}
}}
//ClientProgram
import java.io.*;
import java.net.*;
public class Client
{
private static InetAddress host;
private static final int PORT = 1247;
private static Socket link;
private static BufferedReader in;
private static PrintWriter out;
private static BufferedReader keyboard;
public static void main(String[] args) throws IOException
{
try
{
host = InetAddress.getLocalHost();
link = new Socket(host, PORT);
in = new BufferedReader(
new InputStreamReader(
link.getInputStream()));
out = new PrintWriter(
link.getOutputStream(),true);
keyboard = new BufferedReader(
new InputStreamReader(System.in));
String message, response;
do
{
System.out.print(
"Enter message ('QUIT' to exit): ");
message = keyboard.readLine();
//Send message to server on
//the socket's output stream...
out.println(message);
//Accept response frm server on
//the socket's input stream...
response = in.readLine();
//Display server's response to user...
System.out.println(response);
}while (!message.equals("QUIT"));
}
catch(UnknownHostException uhEx)
{
System.out.println(
"\nHost ID not found!\n");
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
finally
{
try
{
if (link!=null)
{
System.out.println(
"Closing down connection...");
link.close();
}
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
}
}
}
包服务器;
导入java.io.*;
导入java.net。*;
导入java.util.ArrayList;
导入java.util.Vector;
公共类多线程服务器
{
向量客户端=新向量();
向量用户=新向量();
私有静态服务器套接字;
专用静态最终int端口=1247;
公共多线程服务器()引发IOException{
servSocket=新的ServerSocket(端口);
while(true){
Socket client=servSocket.accept();
System.out.println(“\n接受新客户端。\n”);
ClientHandler-handler;
handler=新的ClientHandler(客户);
clients.add(handler);
}
}
公共静态void main(字符串[]args)引发IOException
{
MultithreadedServer ms=新的MultithreadedServer();
}
类ClientHandler扩展线程
{
专用套接字客户端;
中的私有缓冲区读取器;
私人打印输出;
字符串名称、消息、响应;
公用ClientHandler(插座)
{
//设置对关联套接字的引用。。。
客户端=套接字;
尝试
{
in=新的缓冲读取器(
新的InputStreamReader(
client.getInputStream());
out=新的打印机(
client.getOutputStream(),true);
}
捕获(IOE异常)
{
e、 printStackTrace();
}
start();
}
公共无效发送消息(字符串消息){
System.out.println(“它会来这里吗?”);
out.println(“服务器:+msg”);
}
公共无效广播(字符串消息){
//向所有连接的用户发送消息
对于(ClientHandler c:客户){
c、 println(“服务器:您好”);
}
}
公共字符串getUserName(){
返回名称;
}
公开募捐
{
尝试
{
收到字符串;
做
{System.out.println(“输入消息:”);
字符串msg=in.readLine();
out.println(msg);
硼铸(“测试”);
received=in.readLine();
out.println(“ECHO:+已接收”);
//重复上述步骤,直到客户端发送“退出”消息。。。
}而(!received.equals(“QUIT”));
}
捕获(IOE异常)
{
e、 printStackTrace();
}
最后
{
尝试
{
如果(客户端!=null)
{
System.out.println(
“关闭连接…”);
client.close();
}
}捕获(IOE异常)
{
e、 printStackTrace();
}
}
}
}}
//客户程序
导入java.io.*;
导入java.net。*;
公共类客户端
{
专用静态地址主机;
专用静态最终int端口=1247;
专用静态套接字链接;
中的专用静态缓冲读取器;
专用静态打印输出;
专用静态缓冲读取键盘;
公共静态void main(字符串[]args)引发IOException
{
尝试
{
host=InetAddress.getLocalHost();
链路=新套接字(主机、端口);
in=新的缓冲读取器(
新的InputStreamReader(
link.getInputStream());
out=新的打印机(
link.getOutputStream(),true);
键盘=新的BufferedReader(
新的InputStreamReader(System.in));
字符串消息,响应;
做
{
系统输出(
“输入消息('退出'退出):”;
message=keyboard.readLine();
//在上向服务器发送消息
//套接字的输出流。。。
out.println(消息);
//在上接受frm服务器的响应
//套接字的输入流。。。
response=in.readLine();
//显示服务器对用户的响应。。。
System.out.println(响应);
}而(!message.equals(“退出”);
}
捕获(未知后异常uhEx)
{
System.out.println(
“\n找不到主机ID!\n”);
}
捕获(IOException ioEx)
{
ioEx.printStackTrace();
}
最后
{
尝试
{
如果(链接!=null)
{
System.out.println(
“关闭连接…”);
link.close();
}
}
捕获(IOException ioEx)
{
ioEx.printStackTrace();
}
}
}
}
一个显而易见的方法是循环浏览客户端中的所有ClientHandler,并将消息发送给每个客户端:
for (ClientHandler ch : clients){
ch.sendMessage(message); //Or something
}
我做到了,兄弟。同样的问题只有发送消息的客户才会收到服务器的广播消息:(但是每个要接收消息的客户端都被成功接受并添加到客户端列表中?对于我连接的每个客户端,每个客户端都被接受(服务器打印为“新客户端已接受”)。我不知道什么是“添加到客户端列表中”意味着每个ClientHandler都在客户端中。您还可以尝试在ClientHandler中添加调试行,以便在每次调用send()方法时打印消息。您可以确定它是否真的在尝试发送消息。我也尝试过。令我惊讶的是,调试行打印了3次(因为我连接了3个客户端)但是客户机只收到一次服务器消息(我希望客户机也收到三次消息)。