【问题标题】:Sending and reading a 2D array using sockets Java使用套接字 Java 发送和读取二维数组
【发布时间】: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


【解决方案1】:

我看到你的数组中有双倍。您可能想要使用包装类 Double 使其成为一个对象。它使它更容易。您可以序列化原语,但是这样做有一定的限制。

https://www.quora.com/I-know-you-can-serialize-objects-in-Java-but-how-do-you-serialize-primitives-such-as-integers-or-doubles

在这个论坛上,他们问我关于被序列化的原语的相同问题。他们提供的解决方案是……

Java 中的基元具有关联的包装类,它们将您的基元“包装”到一个对象中。从那里,您可以序列化包含您的原语的对象。

包装类.. 例如整数表示 int,Double 表示双精度等。

不确定它是否会清除所有内容,但这是您可能希望在代码中更正的内容。

【讨论】:

    【解决方案2】:

    在这里,我对您的课程进行了一些调整,请看下面。我已经评论了一些东西

    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    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 
            {
               ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
               ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
               //System.out.println(in.readObject());   //you have this here which will read the Double[][]? 
    
                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] = (double) (rowTotal / arrayAvg[row].length);
                    }
                    double max = Double.MIN_VALUE;
                    for(int i = 0; i < average.length; i++) 
                    {
                          if(average[i] > max)
                          {
                             max = average[i];
                          }
                    }
                   // System.out.println((double)in.readObject());  This again won't work you are only sending one thing.
                    //now you did all that stuff with it.... send back to client??
                }
            } catch (IOException e)
            {log("Error handling client# " + clientNumber + ": " + e);} 
            catch (ClassNotFoundException e)
            {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);
        }
    }
    }
    

    上面是你的服务器类,下面是客户端

    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
    
    public class socket_cl
    {
    
    public void connectToServer() throws IOException 
    {
    
        // Get the server address from a dialog box.
    
    
        // Make connection and initialize streams
        Socket socket = new Socket("127.0.0.1", 9898);
        ObjectInputStream in = new ObjectInputStream (socket.getInputStream());
        ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
    
    
        // 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);
    
            //do you want to catch something here from the server? maybe the new Double[][]?  in.readObject?
    
            os.close();
            socket.close();
            Thread.sleep(20 * 1000);
        } 
        catch (InterruptedException e)
        {e.printStackTrace();} 
        catch (Exception e)
        {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) 
      {e.printStackTrace();}
    
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-10
      • 2011-08-19
      • 2019-08-12
      • 1970-01-01
      • 2010-11-13
      相关资源
      最近更新 更多