簡體   English   中英

有什么方法可以通過Socket發送帶有DataOutputStream的Point數組嗎?

[英]Is there any way to send an array of Point with DataOutputStream over a Socket?

我想通過套接字通過DataOutputStream發送一個點數組(Point points [] = new point [20]),並能夠在另一側使用DataInputStream正確讀取它。 我不能單獨發送每個元素,它必須作為一個整體數組發送,並且能夠被解釋為一個整體數組。

請參見“ 高級套接字編程 ”中的“傳輸自定義對象”部分:

  1. 將您的數據放入Serializable類 ,例如MyData。 (由於數組實現了Serializable,因此您實際上不必這樣做,但是以后您可能會希望將其他數據與點數組一起發送...)
  2. 發送方,創建一個MyData對象,並用數據填充它。 將socket.getOutputStream()強制轉換為ObjectOutputStream ,並調用其writeObject方法發送MyData對象。
  3. 接收方,將socket.getInputStream()強制轉換為ObjectInputStream ,並調用其readObject方法以接收對象(您必須將其強制轉換為MyData)。

無論如何,我也將考慮使用RMI 例如,您可以創建一個PointServer,在RMI注冊表中注冊它,然后通過客戶端應用程序中的簡單函數調用來訪問它。 RMI比套接字更容易使用。 例如,您不必設計協議,只需要為分布式對象定義方法。

為什么不改用ObjectInputStream / ObjectOutputStream?

這是我很久以前寫的東西的一段代碼,它可以讓您通過電線發送任何類型的對象,只要它是可序列化的,顯然:

ObjectInputStream input = new ObjectInputStream(communicationSocket.getInputStream());
if (input != null) {
   try {
    Object o = input.readObject();
       if (o != null && o instanceof DataObject) {
      DataObject response = (DataObject) o;
           {
               //Do something cool with DataObject
           }
   }
}//etc...

DataObject只是一個“包裝器” /自定義類,您可以將其定義為具有Point []作為其屬性之一。 換句話說,您可以將DataObject定義為:

import java.io.Serializable;

public class DataObject implements Serializable {

   private Point[] points; //etc - define getter setter for points
}

您可以將其編寫為:

output = new ObjectOutputStream(communicationSocket
                    .getOutputStream());
output.writeObject(yourDataObject);

現在,您可以這樣閱讀:

while (listening) {  
    try {
   Object currentObject = input.readObject();
   if (currentObject != null
    && currentObject instanceof DataObject) {
       Point[] points = ((DataObject) currentObject).getPoints();
           //Do something with points
   }
} 
    catch (IOException e) {
   e.printStackTrace();
} 
    catch (ClassNotFoundException e) {
   e.printStackTrace();
} 
    finally {
   listening = false;
}
}

好吧,您應該了解一些要點,例如,int 32或64位的大小,發送方計算機和接收方計算機的字節順序等。此外,還應該有一個協議來通信兩個套接字,我的意思是,每個發送的數據包中都應該有一個標頭,以便您知道將要接收多少數據,我不會處理,我假設您要發送和接收一個20點的數組。 在此示例中,假設兩台計算機均為32位,即int的大小為4個字節,並且兩台計算機均使用LITTLE_ENDIAN字節順序。

// To send an array of points use these two methods:    
public byte[] pointsToBytes(Point[] p, int numPts)
{
  // 2 is for x and y and 4 is the size of an int in bytes
  ByteBuffer buff = ByteBuffer.allocateDirect(numPts * 2 * 4);
  buff.order(ByteOrder.LITTLE_ENDIAN);
  for (int i = 0; i < numPts; i++)
  {
     buff.putInt(p[i].x);
     buff.putInt(p[i].y);
  }
  return buff.array();
}

public boolean sendData(Point[] pts, int size)
{
  try
  {
      byte[] buffer = pointsToBytes(pts, size);
      mainSocket.getOutputStream().write(buffer, 0, buffer.length);
      return true;
  }
  catch (Exception e)
  {
     e.printStackTrace();
  }
  return false;
}

// To receive an array of point use these two methods:

public Point[] bytesToPoints(byte[] byteBuff, int numBytes)  
{
   ByteBuffer buff = ByteBuffer.wrap(byteBuff);
   buff.order(ByteOrder.LITTLE_ENDIAN);
   // 2 is for x and y and 4 is the size of an int in bytes
   int ptsInBuffer = numBytes / 2 / 4;
   Point[] pts = new Point[ptsInBuffer];
   for (int i = 0; i < ptsInBuffer; i++)
   {
       pts[i].x=buff.getInt();
       pts[i].y=buff.getInt();
   }
   return pts;
 }

 public Point[] getData(int pointsToRead)
 {
    try
    {
        byte[] buffer = new byte[pointsToRead * 4 * 2]; 
        int bytesRead = mainSocket.getInputStream().read(buffer, 0, pointsToRead*4*2);
        return bytesToPoints(buffer, bytesRead);
    }
    catch (Exception e)
    {
       e.printStackTrace();
    }
    return null;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM