我正在为任务做游戏。我有一个用Java设置的服务器和多客户端,我们正在使用MVC。我需要有一个客户端将其名称发送到服务器,然后当有两个玩家出现时,我需要将这两个名称以及他们的玩家编号(玩家1或玩家2)发送回客户端。我不知道如何分辨信息来自哪个线程或信息被发送到哪个线程,因此并非所有玩家都认为自己是玩家之一。谢谢。
在这里,我与您分享了一个不错的 聊天程序 ,其中包含一台服务器,该服务器根据您的要求使用TCP协议与多个客户端进行通信。
程序包含:
使用此程序作为游戏的初始启动器。如果您想在程序中添加新功能,请告诉我。
这是代码(有关更多说明,请参见代码注释):
注意: 在端口号1234上运行此程序之前,请先替换LiveChatClient.java文件中的主机名。
运行程序的步骤:
Opcode.java:
用于设置客户端-服务器通信协议的操作代码
package com.chat;
/**************** an interface to define different operation code **************/
public interface Opcode {
int CLIENT_CONNECTEING = 1;
int CLIENT_CONNECTED = 2;
}
LiveChatServer.java:
控制多个客户端的单个服务器
package com.chat;
/************************ Live Chat Server *******************/
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.LinkedHashMap;
public class LiveChatServer {
// Connection state info
private static LinkedHashMap<String, ClientThread> clientInfo = new LinkedHashMap<String, ClientThread>();
// TCP Components
private ServerSocket serverSocket;
// Main Constructor
public LiveChatServer() {
startServer();// start the server
}
public void startServer() {
String port = "1234";
try {
// in constractor we are passing port no, back log and bind address whick will be local
// host
// port no - the specified port, or 0 to use any free port.
// backlog - the maximum length of the queue. use default if it is equal or less than 0
// bindAddr - the local InetAddress the server will bind to
int portNo = Integer.valueOf(port);
serverSocket = new ServerSocket(portNo, 0, InetAddress.getLocalHost());
System.out.println(serverSocket);
System.out.println(serverSocket.getInetAddress().getHostName() + ":"
+ serverSocket.getLocalPort());
while (true) {
Socket socket = serverSocket.accept();
new ClientThread(socket);
}
} catch (IOException e) {
System.out.println("IO Exception:" + e);
System.exit(1);
} catch (NumberFormatException e) {
System.out.println("Number Format Exception:" + e);
System.exit(1);
}
}
public static HashMap<String, ClientThread> getClientInfo() {
return clientInfo;
}
// *********************************** Main Method ********************
public static void main(String args[]) {
new LiveChatServer();
}
}
LiveChatClient.java:
多个客户端通过服务器互相交谈
package com.chat;
/************************ Live Chat Client *******************/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
public class LiveChatClient {
private String chatName;// current user's chat name(max 7 char if greater than show as 6
// char+...
private String serverAddress;
// TCP Components
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public LiveChatClient() {
initHostName();
runClient();// have fun
}
public void initHostName() {
try {
//replace host name with your computer name or IP address
serverAddress = "[hostname]";
if (serverAddress == null)
System.exit(1);
serverAddress = serverAddress.trim();
if (serverAddress.length() == 0)// empty field
{
System.out.println("Server IP Address or Name can't be blank.");
initHostName();
return;
}
System.out.println("Trying to connect with server...\nServer IP Address:"
+ serverAddress);
// create socket
InetAddress inetAddress = InetAddress.getByName(serverAddress);
if (!inetAddress.isReachable(60000))// 60 sec
{
System.out
.println("Error! Unable to connect with server.\nServer IP Address may be wrong.");
System.exit(1);
}
initPortNo();
} catch (SocketException e) {
System.out.println("Socket Exception:\n" + e);
initHostName();
return;
} catch (IOException e) {
initHostName();
return;
}
}
public void initPortNo() {
try {
String portNo = "1234";
portNo = portNo.trim();
if (portNo.length() == 0)// empty field
{
System.out.println("Server port No can't be blank.");
initPortNo();
return;
}
System.out.println("Trying to connect with server...\nServer Port No:" + portNo);
socket = new Socket(serverAddress, 1234);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println("IO Exception:\n" + e);
initPortNo();
return;
}
}
public void sendChatName() throws IOException {
System.out.println("Enter your name:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = br.readLine();
if (name == null)
System.exit(1);
// title case (get only first 9 chars of chat name)
name = name.trim();
if (name.equalsIgnoreCase("All")) {
System.out.println("This name is already reserved. Try different one.");
sendChatName();
return;
}
if (name.length() == 0) {
System.out.println("Please enter your chat name.");
sendChatName();
return;
}
if (name.length() == 1)
chatName = String.valueOf(name.charAt(0)).toUpperCase();
if (name.length() > 1 && name.length() < 10)
chatName = String.valueOf(name.charAt(0)).toUpperCase()
+ name.substring(1).toLowerCase();
else if (name.length() > 9)
chatName = String.valueOf(name.charAt(0)).toUpperCase()
+ name.substring(1, 10).toLowerCase();
// sending opcode first then sending chatName to the server
out.println(Opcode.CLIENT_CONNECTEING);
out.println(chatName);
}
public void runClient() {
try {
sendChatName();
while (true) {
int opcode = Integer.parseInt(in.readLine());
switch (opcode) {
case Opcode.CLIENT_CONNECTEING:
// this client is connecting
boolean result = Boolean.valueOf(in.readLine());
if (result) {
System.out
.println(chatName + " is already present. Try different one.");
runClient();
}
break;
case Opcode.CLIENT_CONNECTED:
// a new client is connected
Integer totalClient = Integer.valueOf(in.readLine());
System.out.println("Total Client:" + totalClient);
for (int i = 0; i < totalClient; i++) {
String client = in.readLine();
System.out.println((i + 1) + ":" + client);
}
break;
}
}
} catch (IOException e) {
System.out.println("Client is closed...");
}
}
// *********************************** Main Method ********************
public static void main(String args[]) {
new LiveChatClient();
}
}
ClientThread.java:
服务器为每个客户端启动一个多线程,并包含有关所有已连接客户端的信息
package com.chat;
/************************ Client Thread *******************/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
public class ClientThread implements Runnable {
// TCP Components
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private String chatName;
// seperate thread
private Thread thread;
// boolean variable to check that client is running or not
private volatile boolean isRunning = true;
// opcode
private int opcode;
private HashMap<String, ClientThread> clientInfo = new HashMap<String, ClientThread>();
public ClientThread(Socket socket) {
try {
this.socket = socket;
this.clientInfo = LiveChatServer.getClientInfo();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
thread = new Thread(this);
thread.start();
} catch (IOException e) {
System.out.println(e);
}
}
public void run() {
try {
while (isRunning) {
if (!in.ready())
continue;
opcode = Integer.parseInt(in.readLine());// getting opcode first from client
switch (opcode) {
case Opcode.CLIENT_CONNECTEING:
chatName = in.readLine();
boolean result = clientInfo.containsKey(chatName);
out.println(Opcode.CLIENT_CONNECTEING);
out.println(result);
if (result)// wait for another chat name if already present
continue;
// send list of already online users to new online user
// for (Object user : clientInfo.keySet().toArray()) {
// out.println(Opcode.CLIENT_CONNECTED);
// out.println(user.toString());
// }
// put new entry in clientInfo hashmap
clientInfo.put(chatName, this);
int i = 0;
for (String key : clientInfo.keySet()) {
if (key.equals(chatName)) {
System.out.println(chatName + " added at " + (i + 1) + " position");
}
i++;
}
// tell other users about new added user and update their online users list
for (ClientThread client : clientInfo.values()) {
client.out.println(Opcode.CLIENT_CONNECTED);
client.out.println(clientInfo.size());
for (ClientThread client1 : clientInfo.values()) {
client.out.println(client1.chatName);
}
}
break;
}
}
// clsoe all connections
out.close();
in.close();
socket.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
这是添加两个客户端时的输出。
服务器:
ServerSocket[addr=computerName/IPAddress,port=0,localport=1234]
computerName:1234
Abc added at 1 position
Xyz added at 2 position
客户1:
Trying to connect with server...
Server IP Address:computerName
Trying to connect with server...
Server Port No:1234
Enter your name:
abc
Total Client:1
1:Abc
Total Client:2
1:Abc
2:Xyz
客户2:
Trying to connect with server...
Server IP Address:computerName
Trying to connect with server...
Server Port No:1234
Enter your name:
xyz
Total Client:2
1:Abc
2:Xyz
问题内容: 所以现在,我正在制作一个基于客户端服务器应用程序的多线程。在服务器端,我为接受的每个连接创建了一个线程。 在线程类中,我创建了一种将命令发送到客户端的方法。我只想要的是如何将参数发送到所有正在运行的客户端?为简单起见,我只想使此服务器向所有连接的客户端发送消息。 我已经阅读了这篇文章,并从此链接中找到方法。但是,当我尝试使用自己的代码时,中没有类似的方法。 好的,这是我的服务器和线程示
问题内容: 我正在构建一个小型聊天应用程序,其中客户端A希望通过服务器B将某些东西发送到客户端C。首先,这是解决问题的正确方法吗?我能够向服务器发送数据或从服务器接收数据,但仅限于客户端。例如,如果客户端A向服务器B发送数据而客户端C向服务器B发送数据,则我可以将数据发送回服务器A和C就像回显服务器一样。但是我想要的是将来自客户端A的数据通过服务器B转发到客户端C。 以下是服务器代码: 客户端代码
我有一个节点。使用Azure Iot Hub服务与Iot设备通信的js服务器应用程序。 当我检查Azure存储库中关于云到设备消息的示例代码时。我看到了一个客户。如果有多个设备和多条消息要发送到多个设备,创建多个Iot hub客户端可以吗,还是应该坚持使用一个客户端解决方案。两种方法的利弊是什么?
现在我的ServerSocket是这样的 一切正常,客户端连接,发送一些数据,服务器读取它,但我的问题是如何从我的服务器发送消息到所有的客户端?我目前保存客户端上的ArrayList,所以我可以只是循环,ArrayList打开一个作家和刷新它,但我想发送的数据,我得到我的ClientConnection类 我应该如何处理这个代码?在服务器类上完成的所有操作?或
我的查询是针对产品Red Hat AMQ7.x(我使用的是7.2),它基于Apache ActiveMQ Artemis和一个使用AMQP协议连接到队列的.NET客户机。 Artemis的一篇文章讨论了单播(点对点)、多播(发布-订阅)以及这些寻址的组合:https://activemq.apache.org/Artemis/docs/2.0.0/address-model.html 它没有详细说
问题内容: 我写了一个服务器-客户端通信程序,它运行良好。 客户端模块 服务器模块 上面是单个客户端与服务器通信的代码, 现在我希望多个客户端与该服务器进行交互 。我用谷歌搜索它,发现可以通过使用一个线程让每个客户端与服务器对话来完成它,但是由于我是一个初学者,所以我不知道该如何实现。所以有人请告诉我该怎么做或给我一些想法。 问题答案: MainServer类 助手类