【发布时间】:2016-01-19 22:53:13
【问题描述】:
我正在尝试创建一个简单的服务器/客户端实现。我想要做的是从客户端向服务器发送一个填充有随机数的二维数组。然后,服务器将找到 2D 数组的每一行的平均值,并将数组的最大平均值发回并显示出来。我在 StackOverflow 上浏览了多个解决方案,但似乎没有一个对我有用。
我遇到的问题是数组的序列化和反序列化。每次我尝试运行它时,都会收到 StreamCorruptedException 错误。我似乎无法掌握 ObjectoutputStreams 和 ObjectInputStreams。关于我做错了什么,我能得到一两个提示吗?
这是我的服务器端:
public class socket_sr {
public static void main(String[] args) throws Exception {
System.out.println("The server is running.");
int clientNumber = 0;
ServerSocket listener = new ServerSocket(9898);
try {
while (true) {
new Capitalizer(listener.accept(), clientNumber++).start();
}
} finally {
listener.close();
}
}
private static class Capitalizer extends Thread {
private Socket socket;
private int clientNumber;
public Capitalizer(Socket socket, int clientNumber) {
this.socket = socket;
this.clientNumber = clientNumber;
log("New connection with client# " + clientNumber + " at " + socket);
}
public void run() {
try {
InputStream is= socket.getInputStream();
ObjectInputStream in = new ObjectInputStream(is);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
while (true) {
Double[][] arrayAvg = new Double[15][15000];
arrayAvg = (Double [][])in.readObject();
if (arrayAvg == null || in.equals(".")) {
break;
}
/********Do averaging***********/
int rowTotal=0;
int avg=0;
double average[] = new double [arrayAvg.length];
for (int row=0; row<arrayAvg.length; row++){
rowTotal = 0;
for(int col =0; col <arrayAvg[row].length; col++){
rowTotal+=arrayAvg[row][col];
}
average[row] = rowTotal / arrayAvg[row].length;
}
Double max = Double.MIN_VALUE;
for(int i = 0; i < average.length; i++) {
if(average[i] > max) {
max = average[i];
}
}
//Here I am sending the max back to the client side.
out.writeObject(max);
}
} catch (IOException e) {
log("Error handling client# " + clientNumber + ": " + e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
log("Connection with client# " + clientNumber + " closed");
}
}
/**
* Logs a simple message. In this case we just write the
* message to the server applications standard output.
*/
private void log(String message) {
System.out.println(message);
}
}
}
这是我的客户端:
public class socket_cl implements Serializable{
public void connectToServer() throws IOException {
// Get the server address from a dialog box.
// Make connection and initialize streams
Socket socket = new Socket("Host", 9898);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
ObjectInputStream in = new ObjectInputStream (socket.getInputStream());
ObjectOutputStream os = new ObjectOutputStream(outputStream);
// Consume the initial welcoming messages from the server
Double[][] arrays = new Double[15][15000];
try {
for(int i=0; i< 15; i++){
for(int j=0; j<15000;j++){
arrays[i][j]=Math.random()*100;
}
}
os.writeObject(arrays);
//Grab the max from server and display it
Double max= in.readObject();
System.out.println(max);
os.close();
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Stopping Server");
}
public static void main(String[] args) {
socket_cl cl = new socket_cl();
try {
cl.connectToServer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务器正在运行。 在 Socket[addr=/0:0:0:0:0:0:0:1,port=53215,localport=9898] 处与客户端 0 建立新连接
在 Socket[addr=/0:0:0:0:0:0:0:1,port=53216,localport=9898] 处与客户端 1 建立新连接
错误处理客户端# 0:java.io.StreamCorruptedException:无效流标头:47455420
与客户端# 0 的连接已关闭
错误处理客户端#1:java.io.StreamCorruptedException:无效流标头:47455420 与客户端#1 的连接已关闭
在 Socket[addr=/0:0:0:0:0:0:0:1,port=53217,localport=9898] 处与客户端 2 建立新连接
错误处理客户端#2:java.io.StreamCorruptedException:无效流标头:47455420
与客户端#2 的连接已关闭
【问题讨论】:
-
你能把你的错误日志放在这里吗?谢谢
-
您的客户端不需要
implements Serializable。此外,由于 double 不是一个对象,它不能实现可序列化,所以你不能像这样通过流发送它。您必须将其设为Double,使其成为一个对象,您可以将其发送过来。或者创建另一个存储2D double array的类并让该类实现Serializable同样在您的客户端,我没有看到您发送除double[][]之外的任何内容,但在您的服务器上,您accept()不止一件事跨度> -
是否有更好的方法可以推荐传递二维数组,而不是将其作为对象传递。 @3kings
-
@harmanlitt 请看下面我的回答。这就是我的建议。但是您必须将其作为某种形式的对象发送,因为它需要是
Serializable -
@3kings 我稍微改了一下代码,你介意看一下吗?
标签: java arrays sockets server client-server