我是Java Sockets的新手,我看过很多例子,但我无法理解如何将一个参数从服务器传递给客户端,反之亦然。我的目标是传递一个Object,这就是我使用Object I / O Stream的原因。
我必须上课服务器和播放器。
public class Server extends Thread{
public static final int TEST = 165;
ServerSocket serverSocket;
InetAddress address;
Player playerWhite;
public Server() {
start();
}
@Override
public void run() {
try
{
address = InetAddress.getLocalHost();
serverSocket = new ServerSocket(6000);
playerWhite = new Player();
System.out.println("server waits for players");
playerWhite.socket = serverSocket.accept();
playerWhite.start();
sendTestMessage(playerWhite);
}
catch (IOException ex)
{
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendTestMessage(Player player) throws IOException
{
ObjectOutputStream testToClient = new ObjectOutputStream(player.socket.getOutputStream());
testToClient.write(TEST);
testToClient.flush();
}
玩家类:
public class Player extends Thread {
Socket socket;
Player() throws IOException
{
socket = new Socket(InetAddress.getLocalHost(), 6000);
}
@Override
public void run() {
try {
listenTestStream();
}
catch (IOException | ClassNotFoundException ex)
{
Logger.getLogger(CheckerPlayer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void listenTestStream() throws IOException, ClassNotFoundException
{
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
int message = ois.readInt();
//To test
System.out.println("Server listened: " + message);
}
我在另一个类中创建一个Server对象时执行它。
当我测试这个应用程序时,我发现有时候客户端比服务器更快。是否有可能让他“等待”服务器响应? 谢谢你的回复。
编辑1:问题解决方案:
从外面我们应该创造:
Player player = new Player(); // (class player extends from Thread)
player.start();
并删除Player变量 - 没有必要,我们只需要Socket所以: 服务器:
Socket playerWhiteSocket
public void run() {
try
{
serverSocket = new ServerSocket(PORT);
playerWhiteSocket = serverSocket.accept();
sendMessage(playerWhiteSocket, "Hello");
}
catch(IOException | ClassNotFoundException ex)
{}
public void sendMessage(Socket socket, String message) throws IOException
{
ObjectOutputStream testToClient = new ObjectOutputStream(socket.getOutputStream());
testToClient.writeObject(message);
testToClient.flush();
}
在Player类中我们需要get方法:
public String receiveMessage() throws IOException, ClassNotFoundException
{
//socket is a variable get from Player class socket = new Socket("severHost", PORT);
ObjectInputStream messageFromServer = new ObjectInputStream(socket.getInputStream());
String message = (String) messageFromServer.readObject();
return message;
}
答案 0 :(得分:1)
我会建议做这个公开的void start(){
try {
ServerSocket = new ServerSocket(this.port,10,this.localAddress);
// set timeout if you want
//this.clientServerSocket.setSoTimeout(timeout);
// infinity loop
while(true)
{
//wait for a client connection
Socket socket = ServerSocket.accept();
// start thread for every new client
Thread t = new Thread(new AcceptClients(this.socket));
t.start();
System.out.println(L"new client connected");
// call garbage collector and hope for the best
System.gc();
}
} catch (IOException e) {
System.out.println("IO Error");
e.printStackTrace();
}
}
然后在另一个班级
public class AcceptClients implements Runnable{
// socket
private Socket socket;
public AcceptClients (Socket socket){
this.socket = socket;
}
@Override
public void run() {
// what happens if a client connect
}
}
我总是使用它并且工作正常
答案 1 :(得分:1)
建议的更改。
仅创建一次ServerSocket。如果你已经完成了,你就不会得到" Address already in use
"误差
创建服务器套接字后,您的线程应该在while (true)
循环中以接受来自客户端的连接。
创建客户端套接字后,将该套接字传递给线程。
现在,Player用于从服务器向客户端套接字发送通信。所以你还需要一个像PlayerClient
这样的类来创建服务器IP和端口的套接字。现在,PlayerClient应该再创建一个线程来处理IO操作,就像从服务器那样。在这种情况下,创建套接字不在客户端的while循环中。它创建一个服务器套接字一次。现在,您可以从多台计算机上运行此PlayerClient程序。
如果您只是发送原始类型,请使用DataOutputStream & DataInputStream
而不是ObjectStreams
此代码将变为此
try
{
address = InetAddress.getLocalHost();
serverSocket = new ServerSocket(6000);
System.out.println("server waits for players");
while ( true){
Socket socket = serverSocket.accept();
Player playerWhite = new Player(socket);
sendTestMessage(socket);// Move this method to Player thread and change the signature of this method accordingly to accept a socket
}
}
catch (IOException ex)
{
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
Player.java
Player(Socket socket) throws IOException
{
this.socket = socket;
start();
}
请查看此chat示例,以便更好地理解。
答案 2 :(得分:0)
是的。
如果你把它放在像这样的endlees循环中它应该有效:
try
{
while(true){
address = InetAddress.getLocalHost();
serverSocket = new ServerSocket(6000);
playerWhite = new Player();
System.out.println("server waits for players");
playerWhite.socket = serverSocket.accept();
playerWhite.start();
sendTestMessage(playerWhite);
}
}
catch (IOException ex)
{
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
但我不建议把它放在一个帖子里。相反,我会将新客户端的连接放在一个线程中,这样多个客户端就可以连接到服务器