gpt4 book ai didi

java - ObjectOutputStream 方法 writeObject 在 android 上挂起

转载 作者:行者123 更新时间:2023-12-01 05:36:13 29 4
gpt4 key购买 nike

我编写了一些客户端-服务器通信。

我的服务器:

public class Server {


public synchronized static void sendPacket(Packet packet,
ObjectOutputStream server) {

try {
server.writeObject(packet);
server.flush();
} catch (IOException e) {
Log.d(TAG, "Error while sending a packet. Output stream is unaviable.");
}
}

public synchronized static Packet readPacket(ObjectInputStream sourceStream) {
Packet recivedPacket = null;
try {
recivedPacket = (Packet) sourceStream.readObject();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

return recivedPacket;
}


/** Register user on the server */
private User registerUser(Socket socket) {
ClientUserLoginPacket newUserPacket = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
Log.i(TAG, "Opening output stream...");
oos = new ObjectOutputStream(socket.getOutputStream());
if (oos != null)
Log.d(TAG, "Output stream opened");

Log.i(TAG, "Opening input stream...");
ois = new ObjectInputStream(socket.getInputStream());
if (ois != null)
Log.d(TAG, "Input stream opened");

} catch (StreamCorruptedException e1) {
Log.e(TAG, "Error while opening stream");
} catch (IOException e1) {
e1.printStackTrace();
}

// First packet MUST be register request
try {
Log.d(TAG, "Waiting for login packet from client...");
newUserPacket = (ClientUserLoginPacket) readPacket(ois);
Log.d(TAG, "Login packet from recived...");
} catch (Exception e) {
Log.e(TAG, "Can't recive login packet.");
}
User newUserInstance = null;
// TODO check if exists. or to map in the future
if (newUserPacket != null) {
newUserInstance = new User(socket, ois, oos, newUserPacket.nick);
users.add(newUserInstance);
Log.d(TAG, "User " + newUserPacket.nick + " registered.");

Server.sendPacket(new ServerLoginAcceptedPacket(), oos);
Log.d(TAG, "User accept confirmation sent.");
}
return newUserInstance;
}
@Override
public void run() {

Log.i(TAG, "Starting server...");
ServerSocket server;
try {
server = new ServerSocket(PORT);
Log.i(TAG, "Server started.");
server.setSoTimeout(0);

while (true) {
Log.i(TAG, "Waiting for players...");
final Socket socket = server.accept();
Log.i(TAG, "New player connected.");
new Thread(new Runnable() {

@Override
public void run() {
Log.i(TAG, "Try to register new player.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
User user = registerUser(socket);
while (true) {

Log.i(TAG, "Waiting for packets from " + user.nick+"...");
Packet packet = readPacket(user.ois);
Log.i(TAG, "Packet from " + user.nick + " recived.");

if (packet instanceof ...) {
...
}
}
}

}).start();
}

} catch (IOException e) {
Log.i(TAG, "Port is busy.");
}

}


private class User {
public Socket connection;
public ObjectInputStream ois;
public ObjectOutputStream oos;
public String nick;
public boolean inGame;

public User(Socket socket, ObjectInputStream ois,
ObjectOutputStream oos, String nick) {
this.connection = socket;
this.ois = ois;
this.oos = oos;
this.nick = nick;
}
// ...
}

我的客户:

public class Client {
callbackHandler = new Thread(new Runnable() {

@Override
public void run() {

while (true) {

Log.e(TAG, "Waiting for incomeing packets...");
Packet packet = (Packet) Server.readPacket(serverInput);
Log.e(TAG, "Packet recived.");

if (packet instanceof ServerLoginAcceptedPacket) {
Log.e(TAG, "Recived packet is "
+ packet.getClass().toString());
Intent intent = new Intent(MyActivity.this,
MainMenuActivity.class);

MyActivity.this.startActivity(intent);
}
}

}
});


public void connectToServer() {

SocketAddress sockaddr = new InetSocketAddress(mEditTextIp.getText()
.toString(), Server.PORT);
server = new Socket();
try {
server.setSoTimeout(1000);
Log.d(TAG, "Connecting to server.");
server.connect(sockaddr, Server.PORT);
Log.d(TAG, "Connected to server.");
} catch (IOException e) {
Log.e(TAG, "Can't connect to server.");
server = null;
}

if (server != null)
try {
server.setSoTimeout(0);
Log.d(TAG, "Opening output stream...");
serverOutput = new ObjectOutputStream(server.getOutputStream());
if (serverOutput != null)
Log.d(TAG, "Output stream opened");
else
Log.e(TAG, "Error while opening output stream");

} catch (IOException e) {
Log.e(TAG, "Server socket probably closed");
}
}

public void requestLogin() {

new Thread(new Runnable() {

@Override
public void run() {
Log.e(TAG, "Sending login packet...");
Server.sendPacket(new ClientUserLoginPacket(mEditTextLogin
.getText().toString(), ""), serverOutput); // TODO send
// pass and
// email
Log.e(TAG, "Login packet send");
}
}).start();
}

public void authenticate(View v) {

if (server == null)
connectToServer();

if (server != null) {

requestLogin();

try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
serverInput = new ObjectInputStream(server.getInputStream());
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (serverInput != null) {

Log.e(TAG, "Start reciving callbacks...");
callbackHandler.start();
} else {
Log.d(TAG, "Can't open input stream to server.");
}
}

}

public void runServer(View v) {
new Thread(new Server()).start();

Toast.makeText(this, "Server running...", 1000).show();
}
}

其中 runServer()authenticate() 函数通过按钮触发。

问题是,服务器接收 ClientLoginPacket 后,所有后续 sentPacket 函数都卡在 oos.writeObject() 上。

我认为从流中读取/写入流的顺序可能是错误的。打开流并向其中写入对象的正确顺序应该是什么?在打开 ObjectInputStream 之前,我是否必须向 ObjectOutputStream 写入一些内容?

最佳答案

几个小时后,我发现我的方法 readPacket()sendPacket() 之前的关键字 synchronized 有问题。 ;)

关于java - ObjectOutputStream 方法 writeObject 在 android 上挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8169542/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com