我有一个任务,我必须创建一个多线程刽子手游戏 服务器和客户端。我想我会创建一个我将制作游戏的类(Hangman),以及一个带有main方法的Server类,任何try catch块。客户端类将具有将连接到端口并且能够播放的客户端。
我的问题是,如何在我的刽子手游戏中创建客户端并开始将请求作为对象发送到服务器而不是单独的程序?
答案 0 :(得分:0)
在Java中,名为Sockets
的对象可用于通过网络将数据发送到特定的IP和端口。该数据将由正在侦听端口的ServerSocket
接收。
一旦套接字与服务器套接字连接,它将对任何传出呼叫进行排队,直到您调用ServerSocket#accept
为止,
它将接受远程连接并允许应答呼叫(如果在任何呼叫排队之前调用accept
,它将在返回之前等待请求)。 accept
方法返回一个常规套接字对象,它包含用于发送和接收数据的输入和输出流。
注意:每次调用时,多个套接字可以同时对呼叫进行排队
accept()
服务器将接受 next 挂起的套接字。该 accept方法与Scanner
的next()
方法非常相似。它是 令人困惑,但你可以在这里了解更多: ServerSocket listens without accept()
我建议从服务器套接字的输入流(从accept
获取)构建ObejctInputStream
,从客户端套接字的输出流构建ObjectOutputStream
。
如果需要两个套接字发送和接收数据,那么只需在服务器端创建ObjectOutputStream
,在客户端创建ObjectInputStream
。您将需要使用循环或某种类型的Runnable
来监听两个流(您的分配是多线程的,因此Runnable
是最佳选择)。
通常会以类似于此的方式接近客户端套接字:
public class ObjectSocket{
private Socket socket;
private ObjectOutputStream streamOut;
private ObjectInputStream streamIn;
public ObjectSocket(String IP, int port) throws UnknownHostException, IOException {
//Request connection.
this.socket = new Socket(InetAddress.getByName(IP), port);
}
public void sendObject(Object obj) throws IOException {
if(this.streamOut == null) this.streamOut = new ObjectOutputStream(this.socket.getOutputStream());
//Make sure the connection is still there and the socket is still open.
if(this.socket.isConnected() && !this.socket.isClosed())
//Send it!
this.streamOut.writeObject(obj);
}
public Object recieveObject() throws IOException, ClassNotFoundException {
if(this.streamIn == null) this.streamIn = new ObjectInputStream(this.socket.getInputStream());
//Cast appropriately.
return this.streamIn.readObject();
}
public void shutdown() throws IOException {
//End the connection
this.socket.close();
}
}
使用套接字时调用shutdown
方法很重要。让港口保持开放可能很危险。
服务器端套接字几乎以同样的方式接近:
public class ServerObjectSocket {
private ServerSocket servSocket;
private Socket socket;
private ObjectOutputStream streamOut;
private ObjectInputStream streamIn;
public ServerObjectSocket(int port) throws IOException {
//Listen on this port : 0 will listen on a random port.
this.servSocket = new ServerSocket(port);
}
public void acceptConnectionRequest() throws IOException {
//Connect with any client socket that is trying this port
this.socket = servSocket.accept();
}
public Object recieveObject() throws IOException, ClassNotFoundException {
if(this.streamIn == null) this.streamIn = new ObjectInputStream(this.socket.getInputStream());
//Cast appropriately.
return this.streamIn.readObject();
}
public void sendObject(Object obj) throws IOException {
if(this.streamOut == null) this.streamOut = new ObjectOutputStream(this.socket.getOutputStream());
//Make sure the connection is still there and the socket is still open.
if(this.socket.isConnected() && !this.socket.isClosed())
//Send it!
this.streamOut.writeObject(obj);
}
public void shutdown() throws IOException {
//Close the port and end the connection : never leave a port open.
this.servSocket.close();
}
}
请记住,只有当服务器套接字在转发端口上运行时,才能在不同网络上的套接字之间建立连接。在LAN上运行的套接字不会遇到此问题,但可能会对防火墙造成困难。
如果您需要更好的理解或示例,只需在互联网上搜索Java Socket教程。网上有很多有用的教程,并不难发现。