使用套接字Java发送和读取2D数组

时间:2015-10-21 04:22:24

标签: java arrays sockets server client-server

我正在尝试创建一个简单的服务器/客户端实现。我想要做的是从客户端向服务器发送一个填充了随机数的二维数组。然后,服务器将找到2D阵列的每一行的平均值,并发回数组的最大平均值并显示它。我在StackOverflow上浏览了多个解决方案,似乎没有一个对我有用。

我遇到的问题是数组的序列化和非序列化。每次我尝试运行它时都会收到StreamCorruptedException错误。我似乎无法掌握ObjectoutputStreams和ObjectInputStreams。我可以请一两个关于我做错的提示吗?

这是我的服务器端:

  $( document ).ready(function() {

    var CCCardFill = 0;
    var CCExpMonthFill = 0;
    var CCExpYearFill = 0;  

    var CCCardMax = 16;
    var CCExpMonthMax =  2;
    var CCExpYearMax =  4;

   $( "input" ).keyup(function() {
      var CCCardFill = $(".CCCard").val().length;
      var CCExpMonthFill = $(".CCExpMonth").val().length;
      var CCExpYearFill = $(".CCExpYear").val().length;

      if (CCCardFill >= CCCardMax) {
        $(".CCExpMonth").focus();
      }
      if (CCExpMonthFill >= CCExpMonthMax) {
        $(".CCExpYear").focus();
      }
      if (CCExpYearFill >= CCExpYearMax) {
        $(".CCName").focus();
      }

  });

  }); 

这是我的客户方:

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);
        }
    }
}

}

服务器正在运行。 在Socket上与客户端#0的新连接[addr = / 0:0:0:0:0:0:0:1,port = 53215,localport = 9898]

Socket上客户端#1的新连接[addr = / 0:0:0:0:0:0:0:1,port = 53216,localport = 9898]

错误处理客户端#0:java.io.StreamCorruptedException:无效的流标题:47455420

与客户#0的连接已关闭

错误处理客户端#1:java.io.StreamCorruptedException:无效的流标题:47455420 与客户#1的连接已关闭

Socket上客户端#2的新连接[addr = / 0:0:0:0:0:0:0:1,port = 53217,localport = 9898]

错误处理客户端#2:java.io.StreamCorruptedException:无效的流标题:47455420

与客户#2的连接已关闭

2 个答案:

答案 0 :(得分:0)

我看到你的阵列中有两倍。您可能希望使用包装类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为double等。

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

答案 1 :(得分:0)

我在这里对你的课程做了一些调整,请看下面。我评论了一些事情

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();}

}
}