Java 网络让我难以理解

发布于 2024-10-20 16:30:51 字数 339 浏览 3 评论 0原文

我正在为一个班级做一个项目,我们正在创建一个可以通过 LAN 与 2-4 名玩家一起玩的游戏。尽管我们的小组成员都没有做过任何 Java 网络,但我们愚蠢地认为这并不难理解。不管怎样,让网络正常工作的工作落到了我的身上,但我完全不知道如何去做。除了非常基本的东西(例如将字符串从单个客户端传递到服务器)之外,我在网上找不到任何教程。所以我有几个问题。

首先,如何将多个客户端连接到服务器。我需要为每个服务器创建一个新的 ServerSocket 吗?

其次,是否有任何易于使用的库可以为我抽象其中的一些内容?

我知道这些可能是非常基本的问题,但我确实已经做了相当多的阅读,但我仍然一无所获。

I'm doing a project for a class where we are creating a game that can be played with 2-4 players over a LAN. Even though none of our group members had ever done any Java networking before we stupidly decided that it wouldn't be that hard to figure out. Anyway, the job of getting the networking working fell to me, but I am totally lost on how to do it. I can't find any tutorials online except really basic things like passing a string from a single client to a server. So I have a couple of questions.

First, how do I connect multiple clients to a server. Do I need to create a new ServerSocket for each?

Second, are there any easy to use libraries out there that can abstract some of this for me?

I know these are probably pretty basic questions, but I truly have done a fair bit of reading and I'm still getting no where.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

三寸金莲 2024-10-27 16:30:51

Akka远程参与者可能会有所帮助。下面是一个基本的客户端-服务器连接的示例:

// server code
class HelloWorldActor extends UntypedActor {
   public void onReceive(Object msg) {
      getContext().replySafe(msg + " World");
   }
}
remote().start("localhost", 9999).register(
   "hello-service", 
    actorOf(HelloWorldActor.class));

// client code
ActorRef actor = remote().actorFor(
   "hello-service", "localhost", 9999);
Object res = actor.sendRequestReply("Hello");

Akka 确实提高了抽象级别,就像 RPC 一样,因此看起来您只是在与本地对象进行交互。它还有助于提高并发性和可扩展性,但在您的情况下这些可能不太重要。

Akka's remote actors might help. Here's an example of a basic client-server connection:

// server code
class HelloWorldActor extends UntypedActor {
   public void onReceive(Object msg) {
      getContext().replySafe(msg + " World");
   }
}
remote().start("localhost", 9999).register(
   "hello-service", 
    actorOf(HelloWorldActor.class));

// client code
ActorRef actor = remote().actorFor(
   "hello-service", "localhost", 9999);
Object res = actor.sendRequestReply("Hello");

Akka does raise the abstraction level, much like RPC, so that it seems like you're just interacting with local objects. It will also help with concurrency and scalability, but those may be less of a concern in your case.

述情 2024-10-27 16:30:51

由于这是一个学习练习,我建议不要尝试在基本套接字 API 之上寻找库。每个 Java 开发人员都应该知道这些东西是如何工作的。

您在服务器端创建一个 ServerSocket 来侦听端口上的传入连接。坐在循环中等待连接。当您连接到客户端时,最简单的方法是启动一个线程来管理该连接。当客户端关闭连接(或者出现 io 错误 - 连接中断)时,线程终止。

然后您需要设计在线协议。通常,您希望以代表请求类型的 4 个字节 (int) 开始每个请求。然后根据请求类型解释其余部分。对字符串进行编码时,决定是否要使用基于长度的编码或基于终止符的编码。

实际上,通过练习弄清楚这些东西的真正工作原理将是非常有教育意义的。

Since this is a learning exercise, I recommend against trying to find a library on top of basic sockets API. Every Java developer should know how this stuff works.

You create one ServerSocket on the server side to listen for incoming connections on the port. Sit in a loop waiting for connections. When you connect to a client, the easiest approach is to spin up a thread to manage that connection. The thread terminates when the client closes connection (or there is an io error - broken connection).

Then you need to devise the on-wire protocol. Typically you will want start each request with 4 bytes (int) representing a request type. Then interpret the rest based on request type. When encoding strings, decide if you are going to use length-based encoding or terminator-based encoding.

Actually going through the exercise of figuring out how this stuff really works will be very educational.

謸气贵蔟 2024-10-27 16:30:51

尽管我完全同意康斯坦丁的观点,即您应该至少使用一次纯套接字,但您确实提到这是针对软件工程课程的,而且我认为除了必须编写应用程序代码之外,您不应该重新发明另一个网络库。

如果您想要一个库,Apache MinaNetty 是两个基于 Java 的框架,用于分布式网络。

我之前使用过 Mina,它将一些低级套接字复杂性抽象为一个更加事件驱动的框架。查看快速入门指南以及时间服务器示例,并注意以下内容的简单性MinaTimeServer 和 TimeServerHandler 类。只需在处理程序中创建一个会话并将所需的任何逻辑放入 MessageReceived() 中即可。您不必处理将字符串编码为字节数组或编组等问题。

我没有使用 Netty 的经验,所以我不会对此发表评论。

Although I fully agree with Konstantin that you should work with pure sockets at least once, you did mention this is for a software engineering course and I don't think you should reinvent another networking library, on top of having to write your application code.

If you want a library, Apache Mina and Netty are two Java-based frameworks that are used for distributed networking.

I have used Mina before and it abstracts some of the low level socket complexities into a more event-driven framework. Check out this quick-start guide with a time server example and note the simplicity of the MinaTimeServer and the TimeServerHandler classes. Just create a session in your handler and put whatever logic you need in MessageReceived(). You won't have to deal with encoding Strings to byte arrays or marshalling, etc.

I have no experience with Netty so I won't comment on that.

内心旳酸楚 2024-10-27 16:30:51
class ServerListener extends Thread {
  ServerListener() {
    this.serverSocket = new ServerSocket(53123);  // port number, best to use btw 10000 and 65000
  }
  public void run() {
    while(true) {
      Socket s = serverSocket.accept();
      // the previous line blocks until an actual client connects
      new ClientCommunicator(s).start();
    }
  }
}
class ClientCommunicator extends Thread {
  public void run () {
    while (true) {
      try {
        Message msg = s.read();
        processMessage(msg);
      } catch (IOException ex) {
        // connection broke - kill this client
        clientManager.killClient(this);
      }
    }
  }
}
class Client {
  Client() {
    Socket s = new Socket ("localhost", 53123); // use the same port number
    // now start sending messages to the socket / reading messages from it
  }
}
class ServerListener extends Thread {
  ServerListener() {
    this.serverSocket = new ServerSocket(53123);  // port number, best to use btw 10000 and 65000
  }
  public void run() {
    while(true) {
      Socket s = serverSocket.accept();
      // the previous line blocks until an actual client connects
      new ClientCommunicator(s).start();
    }
  }
}
class ClientCommunicator extends Thread {
  public void run () {
    while (true) {
      try {
        Message msg = s.read();
        processMessage(msg);
      } catch (IOException ex) {
        // connection broke - kill this client
        clientManager.killClient(this);
      }
    }
  }
}
class Client {
  Client() {
    Socket s = new Socket ("localhost", 53123); // use the same port number
    // now start sending messages to the socket / reading messages from it
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文