gpt4 book ai didi

java - 从服务器向所有客户端发送消息

转载 作者:行者123 更新时间:2023-11-30 03:28:32 26 4
gpt4 key购买 nike

我正在尝试编写一个即时消息系统......最初,我是这样做的,一旦我让它工作,我将添加 GUI。

一旦客户端向服务器发送消息,服务器就应该将其显示给所有其他客户端。我怎样才能做到这一点?我一直在尝试一些事情,但它一直只显示给发送消息的客户端...

提前致谢!

服务器

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

class Server {
//one per server
static int port = 3000;
private int backlog = 100;
ServerSocket main;
static DataOutputStream dataOut;
static DataInputStream dataIn;
static String scannerMessage;

static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

static class MailServer extends Thread {
//one per client
static int index;
String name = Client.name;

public MailServer(int index, DataInputStream in, DataOutputStream out) {
Server.dataIn = in;
Server.dataOut = out;
this.index = index; // thread index, one per client
}

public void run() {
while (true) {
try {
String receivedMessage = dataIn.readUTF();

//print receivedMessage to all clients

} catch (Exception e) {
break;
}
}
}
}


public Server(int port) throws Exception {
this.main = new ServerSocket(port);
}

// start a serve
public void serve() throws Exception {
int index = 1;
while (true) {
Socket socket = this.main.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dataIn = new DataInputStream(in);
DataOutputStream dataOut = new DataOutputStream(out);

// handle the connection
// keep reading using an infintite loop
System.out.println("Handling connection to Client " + index + "...");
(new MailServer(index, dataIn, dataOut)).start();
index += 1; // add one every time a new client is added
}
}

public static void main(String[] args) throws Exception {

Server s = new Server(port);
System.out.println("Serving....");
s.serve();
}
}

客户端

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

class Client {

static String hostname = "127.0.0.1";
static int port = Server.port;
static Socket socket;
static String name;

static class Sender extends Thread {
DataOutputStream dataOut;
public Sender(DataOutputStream dataOut) {
this.dataOut = dataOut;
}
public void run() {
while(true) {
//get a message from the user
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String message = br.readLine();
dataOut.writeUTF(message);
dataOut.flush();
} catch(Exception e) {
break;
}
}
}
}

static class Receiver extends Thread {
DataInputStream dataIn;
public Receiver(DataInputStream dataIn) {
this.dataIn = dataIn;
}
public void run() {
while(true) {
try {
//RECEIVE A MESAGE FROM THE SERVER (ending in \n)
String msg = dataIn.readUTF();
while (msg != null) {
System.out.println(msg);
msg = dataIn.readUTF();
}
} catch(Exception e) {
break;
}
}
}
}

//client will require host name and the port
public Client(String hostname, int port) throws Exception {
socket = new Socket(hostname, port);
}

public void connect() throws Exception {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dataIn = new DataInputStream(in);
DataOutputStream dataOut = new DataOutputStream(out);

//handle the connection
System.out.println("Handling connection to server...");
Thread sender = new Sender(dataOut);
Thread receiver = new Receiver(dataIn);

sender.start();
receiver.start();

sender.join();
receiver.join();

System.out.println("Client " + Server.MailServer.index);
System.out.println("----------------------");
}

public static void main(String[] args) throws Exception {

Client c = new Client(hostname, port);
c.connect();
}
}

更新:我创建了所有 MailServer 对象的列表,然后迭代它们以将消息发送给所有客户端,正如 JP Moresmau 建议的那样......但现在第一个发送内容的客户端接收所有输出。为什么是这样?我该如何解决它...?谢谢,如果我的问题看起来太明显或愚蠢,我很抱歉,我仍然是一个 Java 菜鸟:(

服务器 - 已更新

package csci2020_assignment51;

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


class Server {
//one per server
static int port = 3000;
private int backlog = 100;
ServerSocket main;
static DataOutputStream dataOut;
static DataInputStream dataIn;
static String scannerMessage;

static List<MailServer> mailServers = Collections.<MailServer>synchronizedList(new ArrayList<MailServer>());


static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

static class MailServer extends Thread {
//one per client
static int index;
String name = Client.name;

public MailServer(int index, DataInputStream in, DataOutputStream out) {
Server.dataIn = in;
Server.dataOut = out;
this.index = index; // thread index, one per client

}

public void run() {
while (true) {
try {
String receivedMessage = dataIn.readUTF();
String outputMessage = "Client " + index + " said: " + receivedMessage;

//print receivedMessage to all clients
for (MailServer mailserver : mailServers) {
dataOut.writeUTF(outputMessage);
}

} catch (Exception e) {
break;
}
}
}
}


public Server(int port) throws Exception {
this.main = new ServerSocket(port);
}

// start a serve
public void serve() throws Exception {
int index = 1;
while (true) {
Socket socket = this.main.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dataIn = new DataInputStream(in);
DataOutputStream dataOut = new DataOutputStream(out);

// handle the connection
// keep reading using an infintite loop
System.out.println("Handling connection to Client " + index + "...");
MailServer mailServer = new MailServer(index, dataIn, dataOut);
mailServer.start();
mailServers.add(mailServer);
dataOut.writeUTF("Client " + index);
index += 1; // add one every time a new client is added
}
}

public static void main(String[] args) throws Exception {

Server s = new Server(port);
System.out.println("Serving....");
s.serve();
}
}

最佳答案

拥有您创建的所有 MailServer 对象的静态列表

 static List<MailServer> servers=Collections.<MailServer>synchronizedList(new LinkedList<MailServer>);
...
MailServer s=new MailServer(index, dataIn, dataOut);
servers.add(s);
s.start();

然后,当其中一个收到消息时,循环遍历所有这些,并且对于所有期望接收者的人,将消息写入其输出。

代码中的大问题是 dataOut 和 dataIn 是唯一的!您需要将它们移至 MailServer 类。每个邮件服务器与一个特定的客户端通信,因此需要有自己的流。

static class MailServer extends Thread {
DataOutputStream dataOut;
DataInputStream dataIn;

您的通知循环将变为:

 for(MailServer mailServer:mailServers){
if (mailServer!=this){
mailServer.dataOut.writeUtf(...);
}
}

我也不明白你希望如何在服务器中获取 Client.name,因为 Client 在另一台机器上运行......现在摆脱它。

关于java - 从服务器向所有客户端发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29635960/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com