[英]How to pass object by socket in java Server Client
我是Java套接字的新手,我看到了很多示例,但我不明白如何將參數從服務器傳遞到客戶端,反之亦然。 我的目的地是傳遞對象,這就是為什么我使用對象I / O流的原因。
我必須對服務器和播放器進行分類。
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();
}
和Player類:
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;
}
我建議做這個公共無效的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
}
}
我總是使用它,並且效果很好
建議的更改。
僅創建一次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(Socket socket) throws IOException
{
this.socket = socket;
start();
}
請看這個聊天示例,以更好地理解。
是的,是的。
如果將其放入如下的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);
}
但是我不建議將其放在線程中。 相反,我會將一個新客戶端的連接放在一個線程中,以便多個客戶端可以連接到服務器
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.