我正在建立一个4人网络扑克游戏。我首先创建一个运行游戏的游戏对象。它创建一个服务器对象。服务器对象产生4个线程,每个线程将处理不同的套接字连接。然后Game对象产生4个玩家对象。每个玩家对象都会有关于玩家的数据,但是现在我只存储他们的输入和输出对象。每个播放器对象创建一个OFCTable
并传递输入和输出连接信息。 OFCTable
个对象是我的客户。它们连接到服务器并来回发送信息。这个示例在我使用DataInputObjects
/ DataOutputObjects
时正常工作,但现在我已将它们切换为ObjectInputObjects
/ ObjectOutputObjects
,它会产生2个客户端{{1}然后抛出和AC异常。我知道我发送数据的方式有很多问题,我想在以后能够发送对象之后解决这个问题。我已经尝试在输入对象之前创建输出对象,它会产生相同的错误。谢谢你的帮助
输出:
OFCTable
游戏类 公共课游戏{
Starting server...
Connecting...
Server Started...
Connection successful
Connection from:/127.0.0.1
Connecting...
Connection successful
Connection from:/127.0.0.1
Connection from:/127.0.0.1
Connecting...
Connection successful
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.refill(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(Unknown Source)
at java.io.ObjectInputStream.readUTF(Unknown Source)
at OFCTable.run(OFCTable.java:785)
at java.lang.Thread.run(Unknown Source)
服务器类
public static void main(String[] args) throws Exception {
Server server = new Server();
Thread thread = new Thread(server);
thread.start();
Player[] Players = new Player[4];
for(int i=0; i<4; i++ )
Players[i] = new Player(i+1);
}
}
玩家类
public class Server implements Runnable{
static ServerSocket serverSocket;
static Socket socket;
static ObjectOutputStream out;
static ObjectInputStream in;
static Users[] user = new Users[4];
public Server() throws Exception{
}
public void run() {
System.out.println("Starting server...");
try {
serverSocket= new ServerSocket(7777);
System.out.println("Server Started...");
while(true){
socket = serverSocket.accept();
for(int i =0;i<4;i++){
System.out.println("Connection from:" +socket.getInetAddress());
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
if(user[i]==null){
user[i]=new Users(out,in,user,i+1);
Thread thread = new Thread(user[i]);
thread.start();
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Users implements Runnable{
static private Deck cards = new Deck();
ObjectOutputStream out;
ObjectInputStream in;
Users[] user = new Users[4];
int Player;
public Users(ObjectOutputStream out, ObjectInputStream in,Users[] user,int Player){
this.out = out;
this.in = in;
this.user = user;
this.Player = Player;
cards.Shuffle();
}
public void run(){
while(true){
try {
String message = in.readUTF();
switch (message) {
case "1":
message = in.readUTF();
for(int i=0;i<4;i++){
if(user[i]!=null){
user[i].out.writeUTF("View");
user[i].out.writeUTF(message);
}
}
cards.Draw();
message = cards.getCurrent().toString();
break;
case "2":
message = "updatenow";
break;
case "Player":
message = "Player";
in.readUTF();
message = "" + Player;
break;
case "CC":
message = "CC";
for(int i=0;i<4;i++){
if(user[i]!=null){
user[i].out.writeUTF(message);
}
}
message = cards.getCurrent().toString();
break;
default:
break;
}
for(int i=0;i<4;i++){
if(user[i]!=null){
user[i].out.writeUTF(message);
}
}
} catch (IOException e) {
e.printStackTrace();
this.in = null;
this.out = null;
}
}
}
}
OFCTable Class(缩短以便只列出需要知道的信息)
public class Player {
Deck deck = new Deck();
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
int Player=0;
public Player(int play) throws Exception{
this.Player = play;
System.out.println("Connecting...");
socket=new Socket("localhost",7777);
System.out.println("Connection successful");
//in = new ObjectInputStream(socket.getInputStream());
//out = new ObjectOutputStream(socket.getOutputStream());
OFCTable input = new OFCTable(socket,Player);
Thread thread = new Thread(input);
thread.start();
}
}
答案 0 :(得分:1)
我从服务器类写的唯一东西是UTF Strings
我怀疑你没有小心一次只包装你的Socket's Stream。使用数据流,如果您不使用任何缓冲(这会影响性能),您可以多次包装它们
使用对象流,您必须小心只将流包裹一次,并且只使用那个包裹。你必须这样做,因为这些包装器是有状态的,你不能只是按你喜欢的方式混合它们。
BTW如果你只使用readUTF / writeUTF,你只需要带有缓冲区的数据流。