2016-03-21 76 views
0

以下代碼用於通過以下formart「address,porttNum」中的簡單字符串發送。Java UDP數據包僅包含5個數據包

下面是客戶端:

ByteArrayInputStream bin = new ByteArrayInputStream(packet.getData()); 
DataInputStream dis = new DataInputStream(bin); 

try { 
      System.out.println("Data in packet: " + dis.readLine()); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 

下面是服務器端:

byte[] sbuf = data.getBytes(); 
     // sbuf = output.getBytes(); 
     packet = new DatagramPacket(sbuf, 
       sbuf.length, packet.getAddress(), packet.getPort()); 
try { 
      socket = new DatagramSocket(); 
      socket.send(packet); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

說服務器發送 「ABCDEFGHI」,客戶端只臨危 「ABCDE」。我已經嘗試了多個測試用例,客戶端總是收到5個字節。任何人都可以指出我搞砸了嗎?

編輯: 對於調試目的,我甚至增加了以下內容:

try { 
      System.out.println("Data in packet: " + dis.readLine()); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 

其輸出端仍然沒有得到它正確的數據。

編輯2: 我改變了客戶端於以下內容:

String data = new String(packet.getData(), StandardCharsets.UTF_8); 
     System.out.println("Data in packet: " + data); 

這沒有什麼區別。

+0

目前看起來不錯。如果你的輸入中有任何換行符,''readLine()''會把它搞亂...... – f1sh

+2

'DataInputStream'應該和'DataOutputStream'匹配。你的服務器代碼只顯示'data.getBytes()',不知道'data'是什麼,或者它是如何產生的。 'DataInputStream#readLine()'已棄用。 – AJNeufeld

+1

你可能會嘗試使用'new String(packet.getData(),StandardCharsets.UTF_8)'''將字節轉換爲字符串。我沒有看到在這裏使用'DataInputStream'的原因。可能會導致問題,因爲@ f1sh指出。 –

回答

1

下面是一些示例代碼,顯示了從字符串的字節構造數據報包,發送它以及重構字符串。

請注意,接收數據包的緩衝區被創建得比最終收到的消息大得多。這是必要的,因爲如果接收到大於緩衝區的消息,UDP套接字會將消息截斷爲緩衝區的大小。例如,如果客戶端向服務器發送了消息「ZYXWV」,並且僅創建了足夠大的緩衝區,並且重複使用了傳入消息的緩衝區,則只有傳入消息的前5個字符是接收。

public class DataGram { 

    public static void main(String[] args) throws SocketException { 
     new Thread(new Client()).start(); 
     new Thread(new Server()).start(); 
    } 

    static class Client implements Runnable { 
     DatagramSocket socket; 

     Client() throws SocketException { 
      socket = new DatagramSocket(1234); 
     } 

     @Override 
     public void run() { 
      byte[] buf = new byte[1024]; 
      DatagramPacket packet = new DatagramPacket(buf, buf.length); 
      try { 
       try { 
        socket.receive(packet); 
        String msg = new String(packet.getData()); 
        System.out.println(msg); 
       } finally { 
        socket.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    static class Server implements Runnable { 

     @Override 
     public void run() { 
      SocketAddress address = new InetSocketAddress("localhost", 1234); 
      try (DatagramSocket socket = new DatagramSocket()) { 
       String msg = "abcdefghi"; 
       byte[] buf = msg.getBytes(); 
       DatagramPacket packet = new DatagramPacket(buf, buf.length, address); 
       socket.send(packet); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

沒有DataInputStream類或ByteArrayInputStream的用在這裏,因爲你可以直接將Stringbyte[],然後再返回。

+0

我提出了建議的編輯。沒有成功。我應該注意到,我正在線程服務器端。不知道這將如何改變。謝謝您的幫助! – mjr

+1

@mjr在我們可以進一步幫助你之前,你將不得不發佈更多的代碼(儘量減少它仍然存在的問題)。我已經指出你的客戶端正在使用'ByteArrayInputStream'和'DataInputStream',但是在你的服務器代碼中沒有使用這樣的對等物;一個'DataOutputStream'應該被用作DataInputStream的來源等。我已經指出,如果你沒有指定足夠大的緩衝區,UDP數據包將丟失數據。我給了你一個工作示例來與你的代碼進行比較。沒有看到更多的代碼,我們所能做的只是猜測。 – AJNeufeld

+0

我修好了。問題在於我沒有從客戶端更改我的原始buf,因此只能收到與發送的原始字符串的長度一樣多的字母。 – mjr