gpt4 book ai didi

java - 发送消息到特定的客户端线程

转载 作者:行者123 更新时间:2023-12-03 11:55:35 24 4
gpt4 key购买 nike

我有这个服务器类(class),

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
public static ArrayList<String> waiting = new ArrayList<String>();
public static ArrayList<String> playing = new ArrayList<String>();
public static ArrayList<Integer> score = new ArrayList<Integer>();

public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(4321);
while (true) {
try {
Socket socket = server.accept();
new EchoThread(socket).start();
} catch (Exception exc) {
exc.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

public void addClient(String name) {
waiting.add(name);
}

public int getNumClients() {
return waiting.size();
}

public String getClientName(int i) {
return waiting.get(i);
}

public void play() {
int scr = 0;
for (int i = 0; i < 4; i++) {
playing.add(waiting.get(0));
score.add(scr);
waiting.remove(0);
}
}

public boolean checkIfPlaying(String name) {
if (playing.indexOf(name) >= 0) {
return true;
} else {
return false;
}
}
}

和线程类,
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class EchoThread extends Thread {
protected Socket socket;

public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}

public void run() {
Server s = new Server();
DataInputStream in = null;
DataOutputStream out = null;
String line;

try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}

while (true) {
try {
line = in.readLine();
String[] prot = line.split(":");

if (prot[0].equals("/login")) {
s.addClient(prot[1]);
} else if (prot[0].equals("/waiting")) {
if (s.checkIfPlaying(prot[1])) {
out.writeBytes("Playing" + "\r\n");
} else {
if (s.getNumClients() >= 4) {
s.play();
out.writeBytes("Playing" + "\r\n");
} else {
out.writeBytes(s.getNumClients() + "\r\n");
}
}
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}

如果客户端连接到服务器,则客户端的名称将存储在服务器类数组中,等待。
如果等待的客户端等于4,它将从等待的数组中删除并将其放入正在播放的数组中。

我想让服务器将消息发送到播放数组中的前4个客户端。

我该怎么做?

最佳答案

对于服务器类,我将等待和播放的ArrayList 更改为ArrayList 。这样,您的服务器类将跟踪每个客户端对象本身,而不仅仅是它们的名称。当实例化EchoThread对象时,我会将本地服务器对象传递给每个EchoThread,这样每个对象都知道实例化它们的服务器。

服务器等级

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
public ArrayList<EchoThread> waiting = new ArrayList<EchoThread>();
public ArrayList<EchoThread> playing = new ArrayList<EchoThread>();
public ArrayList<Integer> score = new ArrayList<Integer>();

public static void main(String[] args) {
try {
// Instantiate a single server object that you can pass into your connected clients
Server myServer = new Server();
ServerSocket server = new ServerSocket(4321);
while (true) {
try {
Socket socket = server.accept();
// Pass myServer into Echo Thread
new EchoThread(myServer, socket).start();
} catch (Exception exc) {
exc.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

// Have to synchronize this since multiple clients could be adding to this list at the same time
public synchronized void addClient(EchoThread client) {
waiting.add(client);
}

public int getNumClients() {
return waiting.size();
}

public String getClientName(int i) {
return waiting.get(i).getCName();
}

public void play() {
int scr = 0;
for (int i = 0; i < 4; i++) {
EchoThread clientBeingMovedToPlaying = waiting.get(0);
playing.add(clientBeingMovedToPlaying);
score.add(scr);
waiting.remove(0);

// This will be a new method in your EchoThread class
clientBeingMovedToPlaying.SendServerPlayingMessage();
}
}

public boolean checkIfPlaying(String name) {
boolean isPlaying = false;
for(EchoThread client : playing) {
if (client.getName().contentEquals(name)) {
isPlaying = true;
break;
}
}
return isPlaying;
}
}

对于您的Echo Thread类,我将在您的run方法类变量中创建您的变量,以便可以在整个类中使用它们

EchoThread类
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class EchoThread extends Thread {
protected Socket socket;
protected Server s;
protected DataInputStream in;
protected DataOutputStream out;
protected String line;
protected String clientName;

// This way, each EchoThread object knows about the server
public EchoThread(Server theServer, Socket clientSocket) {
this.s = theServer;
this.socket = clientSocket;
}

public void run() {
try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}

while (true) {
try {
line = in.readLine();
String[] prot = line.split(":");

if (prot[0].equals("/login")) {
// Original code
//s.addClient(prot[1]);

// New code
clientName = prot[1];
s.addClient(this);
} else if (prot[0].equals("/waiting")) {
if (s.checkIfPlaying(prot[1])) {
out.writeBytes("Playing" + "\r\n");
} else {
// You don't want multiple clients firing the play method, so you need to synchronize your server object
synchronized (s) {
if (s.getNumClients() >= 4) {
s.play();
out.writeBytes("Playing" + "\r\n");
} else {
out.writeBytes(s.getNumClients() + "\r\n");
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}

public String getCName() {
return clientName;
}

public void SendServerPlayingMessage() {
if (out != null) {
// Send whatever message you want
}
}
}

我想这会满足您的需求...原谅任何语法或逻辑错误,目前我还没有IDE。

关于java - 发送消息到特定的客户端线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29492400/

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