Java UDP数据包仅包含5个数据包

问题描述:

以下代码用于通过以下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指出。 –

下面是一些示例代码,显示了从字符串的字节构造数据报包,发送它以及重构字符串。

请注意,接收数据包的缓冲区被创建得比最终收到的消息大得多。这是必要的,因为如果接收到大于缓冲区的消息,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