问题
I have an assignment where I have to create a multithreaded hangman game with a server and client. I am thinking that will I create a class where I will make the game(Hangman), and a Server class with the main method any the try catch block. A client class will have the client which will connect to the port and will be able to play.
My question is, how can I create the client in my hangman game and start sending the requests to the server as objects and not as a separate program?
回答1:
In Java, objects called Sockets can be used to send data across a network to a specific IP and port. That data will be received by a ServerSocket that is listening on the port.
Once a socket connects with a server-socket it will queue any outgoing calls until you invoke ServerSocket#accept,
which will accept the remote connection and allow calls to be answered (if you invoke accept
before any calls are queued, it will wait for a request before returning). The accept
method returns a regular socket object which has both input and output streams for sending and receiving data.
NOTE: Multiple sockets can queue calls at the same time, every time you invoke
accept()
the server will accept the next pending socket. The accept method works a lot like a Scanner'snext()
method. It is confusing, but you can learn more about it here: ServerSocket listens without accept().
I would suggest constructing an ObejctInputStream from the server-socket's input stream (obtained from accept
), and an ObjectOutputStream from the client-socket's output stream.
If need both sockets to send and receive data, then simply create an ObjectOutputStream
on the server side, and an ObjectInputStream
on the client side. You will need to use a loop, or some type of Runnable to listen on both streams (Your assignment is multithreaded, so Runnable
is the best option).
Typically one would approach client sockets in a manner similar to this:
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();
}
}
It is important to call the shutdown
method when you are finished using the socket. Leaving ports open can be dangerous.
The server side sockets are approached almost the same way:
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();
}
}
Keep in mind, a connection between sockets on different networks is only possible when the server socket in running on a forwarded port. Sockets running on LANs do not face this issue, but might have difficulty with the firewall.
If you need a better understanding or example, just search the internet for Java Socket tutorials. There are plenty of useful tutorials floating around the web, and they are not hard to find.
来源:https://stackoverflow.com/questions/47140278/using-an-instance-of-an-object-as-a-client-in-java