检查是否有传入套接字
Checking if there is an incoming socket
我正在为我的游戏创建服务器,但这个问题更 java 相关。所以我想检查他们是一个传入的套接字,但我仍然想 运行 游戏,因为服务器由用户托管,而不是由外部程序分开。但我仍然想检查是否有人使用套接字进行连接。我现在拥有的是:
public void updateConnection() throws IOException {
Socket connection = server.accept();
System.out.println("Ape is connecting");
ServerClient client = new ServerClient(connection);
clientsWaiting.add(client);
}
我希望每一帧都使用此方法,而不是连续检查是否可行。如果不可能,我还应该用什么来创建我的服务器并检查是否有一些连接每个框架。
最好的办法是让您的游戏在单独的线程中检查传入的套接字连接。您可以创建一个只持续侦听连接的 Runnable
。
当您检查传入连接时:Socket connection = server.accept();
,实际发生的是您在该特定线程上放置一个块,直到您收到连接。这将导致您的代码停止执行。解决这个问题的唯一方法是并行化。您可以在一个线程上处理所有网络任务,同时在另一个线程上处理您的游戏逻辑和渲染。
不过请注意,在多线程上编写 运行 代码有很多陷阱。 Java 提供了一些工具来最大程度地减少潜在问题,但是由您(程序员)来确保您的代码是线程安全的。详细讨论有关并行编程的许多问题超出了这个问题的范围。我建议您对此做一些研究,因为这种类型的编程产生的错误有时很难重现和跟踪。
既然我已经给了你这个免责声明,要使用 Runnable
来完成你想要做的事情,你可以做类似的事情:
Runnable networkListener = () -> {
//declare and instantiate server here
while(true){
Socket connection = server.accept();
//whatever you would like to do with the connection would go here
}
}
Thread networkThread = new Thread(networkListener);
networkThread.start();
您可以将它放在游戏循环之前,它会生成一个线程来侦听连接而不会中断您的游戏。有很多关于如何处理 Socket
s 使用 ThreadPool
s 来跟踪它们的好习惯用法,每次建立新连接时都会产生一个新的 Thread
,所以我建议你对此也做一些研究。
祝你好运,这不是一条你要冒险的好路。
再补充一点:当你建立TCP连接时,你不是在处理帧(UDP是基于帧的协议),你是在处理字节流。
下杠杆Byteoutpustream例子:
InputStream inputStream = socket.getInputStream();
// read from the stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] content = new byte[ 2048 ];
int bytesRead = -1;
while( ( bytesRead = inputStream.read( content ) ) != -1 ) {
baos.write( content, 0, bytesRead );
} // while
因此,当客户端完成写入但流仍处于打开状态时,您的读取方法将阻塞。如果你期望来自客户端的某些数据,你读取它然后调用你的打印方法或者你想要通知等等......
我正在为我的游戏创建服务器,但这个问题更 java 相关。所以我想检查他们是一个传入的套接字,但我仍然想 运行 游戏,因为服务器由用户托管,而不是由外部程序分开。但我仍然想检查是否有人使用套接字进行连接。我现在拥有的是:
public void updateConnection() throws IOException {
Socket connection = server.accept();
System.out.println("Ape is connecting");
ServerClient client = new ServerClient(connection);
clientsWaiting.add(client);
}
我希望每一帧都使用此方法,而不是连续检查是否可行。如果不可能,我还应该用什么来创建我的服务器并检查是否有一些连接每个框架。
最好的办法是让您的游戏在单独的线程中检查传入的套接字连接。您可以创建一个只持续侦听连接的 Runnable
。
当您检查传入连接时:Socket connection = server.accept();
,实际发生的是您在该特定线程上放置一个块,直到您收到连接。这将导致您的代码停止执行。解决这个问题的唯一方法是并行化。您可以在一个线程上处理所有网络任务,同时在另一个线程上处理您的游戏逻辑和渲染。
不过请注意,在多线程上编写 运行 代码有很多陷阱。 Java 提供了一些工具来最大程度地减少潜在问题,但是由您(程序员)来确保您的代码是线程安全的。详细讨论有关并行编程的许多问题超出了这个问题的范围。我建议您对此做一些研究,因为这种类型的编程产生的错误有时很难重现和跟踪。
既然我已经给了你这个免责声明,要使用 Runnable
来完成你想要做的事情,你可以做类似的事情:
Runnable networkListener = () -> {
//declare and instantiate server here
while(true){
Socket connection = server.accept();
//whatever you would like to do with the connection would go here
}
}
Thread networkThread = new Thread(networkListener);
networkThread.start();
您可以将它放在游戏循环之前,它会生成一个线程来侦听连接而不会中断您的游戏。有很多关于如何处理 Socket
s 使用 ThreadPool
s 来跟踪它们的好习惯用法,每次建立新连接时都会产生一个新的 Thread
,所以我建议你对此也做一些研究。
祝你好运,这不是一条你要冒险的好路。
再补充一点:当你建立TCP连接时,你不是在处理帧(UDP是基于帧的协议),你是在处理字节流。 下杠杆Byteoutpustream例子:
InputStream inputStream = socket.getInputStream();
// read from the stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] content = new byte[ 2048 ];
int bytesRead = -1;
while( ( bytesRead = inputStream.read( content ) ) != -1 ) {
baos.write( content, 0, bytesRead );
} // while
因此,当客户端完成写入但流仍处于打开状态时,您的读取方法将阻塞。如果你期望来自客户端的某些数据,你读取它然后调用你的打印方法或者你想要通知等等......