Java 中的多人游戏。将客户端(玩家)连接到其他客户端创建的游戏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29545597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:28:35  来源:igfitidea点击:

Multiplayer game in Java. Connect client (player) to game that was created by other client

javasocketsmultiplayer

提问by Richard H.

I am working on multiplayer game and I cant to find out how can I connect other clients to the created game. I mean that client A create a socket connection to the server and how other clients (A,B...) can connect to the client A? Can somebody help me please?

我正在开发多人游戏,但不知道如何将其他客户端连接到创建的游戏。我的意思是客户端 A 创建到服务器的套接字连接以及其他客户端(A,B ...)如何连接到客户端 A?有人可以帮我吗?

P.S. I'm new with network programming, so if you can attach some example i would be very grateful.

PS我是网络编程的新手,所以如果你能附上一些例子,我将不胜感激。

回答by tirz

Another client cannot be connected to the Client A because of his firewall.

由于防火墙的原因,另一个客户端无法连接到客户端 A。

You can create two majors kinds of network:

您可以创建两种主要类型的网络:

  • Server-Client

  • Peer-to-Peer

  • 服务器-客户端

  • 点对点

But a client can save some data to the server and the server can send them to all the clients (you don't need a Peer-to-Peer network for allow the Client B to send some data to the Client A).

但是客户端可以将一些数据保存到服务器,服务器可以将它们发送给所有客户端(您不需要点对点网络来允许客户端 B 向客户端 A 发送一些数据)。

Example: The Client B send his map position to the server, the server send the data to all the clients, so the Client A is able to draw a character tileset at the position of the Client B.

示例:客户端 B 将自己的地图位置发送给服务器,服务器将数据发送给所有客户端,因此客户端 A 可以在客户端 B 的位置绘制字符图块集。

For connect two PCs together, you need to forward a port from the modem of your server to the PC used as server, and open the port from the firewall of the PC used as server.

要将两台PC连接在一起,您需要将服务器调制解调器的端口转发到用作服务器的PC,并从用作服务器的PC的防火墙打开该端口。

You can also take a look here Creating a Multiplayer game in python, I give an example where the clients was able to connect them together with IRC and play at a Tic-Tac-Toe game (so you didn't have to manage a server). I have add an example in Java at the end of this post.

您还可以查看在 python 中创建多人游戏,我举了一个例子,其中客户端能够将它们与 IRC 连接在一起并玩 Tic-Tac-Toe 游戏(因此您不必管理服务器)。我在本文末尾添加了一个 Java 示例。

A simple server example:

一个简单的服务器示例:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;


public class Server
{
    public static void main(String[] args) throws Exception
    {
        ServerSocket listener = new ServerSocket(4000);
        String line;
        try
        {
            while (true)
            {
                Socket socket = listener.accept();
                BufferedReader readerChannel = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                BufferedWriter writerChannel = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                try
                {
                    writerChannel.write(new Date().toString() + "\n\r");
                    writerChannel.flush();

                    while ((line = readerChannel.readLine()) != null)
                    {
                        System.out.println(line);
                    }
                }
                finally
                {
                    socket.close();
                }
            }
        }
        finally
        {
            listener.close();
        }
    }
}

A simple client example:

一个简单的客户端示例:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;


public class Client
{
    public static void main(String[] args) throws Exception
    {
        Socket socket = new Socket("127.0.0.1", 4000);
        BufferedWriter writerChannel = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        BufferedReader readerChannel = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;

        writerChannel.write(new Date().toString() + "\n\r");
        writerChannel.flush();

        while ((line = readerChannel.readLine()) != null)
        {
            System.out.println(line);
        }
    }
}

Also take a look at:

另请看:

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;


public class Client
{
    public static void main(String[] args) throws Exception
    {
        SSLSocketFactory socketBuilder = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket socket = (SSLSocket) socketBuilder.createSocket("127.0.0.1", 4000);
    }
}

A simple IRC example:

一个简单的 IRC 示例:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;


public class Client
{
    public static void main(String[] args) throws Exception
    {
        SSLSocketFactory socketBuilder = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket socket = (SSLSocket) socketBuilder.createSocket("irc.freenode.net", 6697);
        BufferedWriter writerChannel = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        BufferedReader readerChannel = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        String line, computerName, nick, login, channel = "#bot", channelPassword = "";
        long id = 1;

        computerName = java.net.InetAddress.getLocalHost().getHostName();
        nick = computerName + "_" + id;
        login = computerName + "_" + id;
        writerChannel.write("NICK " + nick + "\r\n"); // Join IRC with a specific Nick
        writerChannel.write("USER " + login + " 8 * :" + login + " \r\n"); // Join IRC with a specific User
        writerChannel.flush();

        while ((line = readerChannel.readLine()) != null)
        {
            if (line.indexOf("004") != -1) // If connected
            {
                break;
            }
            else if (line.indexOf("433") != -1) // If Nick already in use
            {
                id++;
                nick = computerName + "_" + id;
                login = computerName + "_" + id;
                writerChannel.write("NICK " + nick + "\r\n");
                writerChannel.write("USER " + login + " 8 * :" + login + " \r\n");
                writerChannel.flush();
            }
        }

        writerChannel.write("JOIN " + channel + " " + channelPassword + "\r\n"); // Join a channel
        writerChannel.flush();

        while ((line = readerChannel.readLine()) != null)
        {
            try
            {
                line = line.substring(line.indexOf("#"));
                channel = line.substring(0, line.indexOf(" "));

                if (line.toLowerCase().startsWith("ping")) // avoid ping time-out
                {
                    writerChannel.write("PONG :" + line.substring(5) + "\r\n");
                    writerChannel.flush();
                }
                else if (line.toLowerCase().contains("!ping"))
                {
                    writerChannel.write("PRIVMSG " + channel + " :pong\r\n");
                    writerChannel.flush();
                }
                else if (line.toLowerCase().contains("!join"))
                {
                    String newChannel = line.substring(line.indexOf("!join") + 6);
                    int stringPosition;
                    if ((stringPosition = newChannel.indexOf(" ")) != -1)
                    {
                        String newPassword = newChannel.substring(stringPosition + 1);
                        newChannel = newChannel.substring(0, stringPosition);
                        writerChannel.write("JOIN " + newChannel + " " + newPassword + "\r\n");
                        writerChannel.flush();
                    }
                    else
                    {
                        writerChannel.write("JOIN " + newChannel + "\r\n");
                        writerChannel.flush();
                    }
                }
                else if (line.toLowerCase().contains("!leave"))
                {
                    writerChannel.write("PART " + channel + "\r\n");
                    writerChannel.flush();
                }
                else if (line.toLowerCase().contains("!quit"))
                {
                    writerChannel.write("QUIT\r\n");
                    writerChannel.flush();
                    System.exit(0);
                }
            }
            catch (Exception e)
            {

            }
        }
    }
}

I cannot give you an example for a Peer-to-Peer network because I have never do it. This is really difficult and you have to do a lot of research on internet.

我不能给你一个点对点网络的例子,因为我从来没有这样做过。这真的很难,你必须在互联网上做很多研究。

More informations:

更多信息:

Hint - I have already answer at some similar questions. Even if the programming language are sometime different, I give you the link, the logic is always the same so it can maybe help you:

提示 - 我已经回答了一些类似的问题。即使编程语言有时不同,我给你链接,逻辑总是相同的,所以它可能会帮助你:

回答by Warren Dew

Here is one way to handle it. When a player wants to create a game, his copy of the application should open a ServerSocket on a known port - a port number that the application knows - and maybe display to the player the IP address that the socket was opened on.

这是处理它的一种方法。当玩家想要创建游戏时,他的应用程序副本应该在已知端口(应用程序知道的端口号)上打开 ServerSocket,并且可能向玩家显示打开套接字的 IP 地址。

Then when another player wants to join a game, she should enter that same IP address and her copy of the application should connect using a regular client Socket, the IP address entered, and the known port that the application knows.

然后,当另一个玩家想要加入游戏时,她应该输入相同的 IP 地址,并且她的应用程序副本应该使用常规客户端 Socket、输入的 IP 地址和应用程序知道的已知端口进行连接。

Check the Socket and ServerSocket javadoc for details.

有关详细信息,请查看 Socket 和 ServerSocket javadoc。