具有多客户端通信的 Java 服务器. [英] Java Server with Multiclient communication.

查看:27
本文介绍了具有多客户端通信的 Java 服务器.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一项任务制作游戏.我有一个用 Java 设置的服务器和多客户端,我们正在使用 MVC.我需要让客户端将他们的名字发送到服务器,然后当有两个玩家存在时,我需要将两个名字以及他们的玩家编号(玩家一号或玩家二号)发送回客户端.我不知道如何判断信息来自哪个线程或信息被发送到哪个线程,因此并非所有玩家都认为他们是玩家之一.谢谢.

I'm making a game for an assignment. I have a server and multiclient set up in Java and we're using MVC. I need to have a client send their name to the server and then when two players are present I need to send both names back to the clients along with which player number they are (player one or player two). I don't get how I could tell which thread the information is coming from or which thread the information is getting sent to so not all players think they are player one. Thanks.

推荐答案

在这里我向您分享了一个很好的聊天程序,它有一个服务器,它根据您的要求使用 TCP 协议与多个客户端进行通信.

Here I am sharing you a nice Chat Program having one server that is communicating with multiple clients using TCP protocol as per your requirement.

程序包含:

  • 无论何时添加新客户,都会通知每位客户及其姓名和职位.
  • 它还检查现有名称.程序不允许多个客户端使用相同的名称.

使用此程序作为您游戏的初始启动器.如果您想在程序中添加新功能,请告诉我.

Use this program as initial starter for your game. Please let me know if you want to add new functionality in the program.

这是代码(请参阅代码注释以获得更多说明):

Here is the code (see code comments for more clarification):

注意:在端口号1234运行此程序之前替换LiveChatClient.java文件中的主机名

Note: replace host name in LiveChatClient.java file before running this program at port no 1234

运行程序的步骤:

  • 第一次只运行一次 LiveChatServer
  • 然后为您想要添加的多个客户端运行 LiveChatClient

Opcode.java:

用于设置客户端-服务器通信协议的操作代码

Operation code that is used to set a client-server communication protocol

package com.chat;

/**************** an interface to define different operation code **************/

public interface Opcode {
    int CLIENT_CONNECTEING = 1;
    int CLIENT_CONNECTED = 2;
}

LiveChatServer.java:

控制多个客户端的单个服务器

Single server that is controlling multiple clients

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:

多个客户端通过服务器相互通信

Multiple clients talking to each other via server

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...
Server 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.
Server IP Address may be wrong.");
                System.exit(1);
            }

            initPortNo();
        } catch (SocketException e) {
            System.out.println("Socket Exception:
" + 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...
Server 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:
" + 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:

由服务器为每个客户端启动的多个线程,并包含有关所有已连接客户端的信息

Multiple thread started by server one for each client and containing information about all connected clients

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);
        }
    }
}

这是添加两个客户端时的输出.

Here is the output when two client are added.

服务器:

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

这篇关于具有多客户端通信的 Java 服务器.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆