如何在使用UDP的java网络中使用flush()

问题描述 投票:0回答:2

我正在尝试使用基本的UDP在java中进行双向服务器-客户端通信,但问题是,如果我输入一个字符串,它就会溢出,所以我认为使用flush()来刷新缓冲区是很好的,但是我不知道如何使用这个功能

UDP 中的服务器代码

    import java.io.*;
import java.net.*;

class servee
{
   public static void main(String args[]) throws Exception
      {
         DatagramSocket serverSocket = new DatagramSocket(9876);
            byte[] receiveData = new byte[1024];
            byte[] sendData = new byte[1024];
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
            while(true)
               {
                  DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                  serverSocket.receive(receivePacket);
                  String sentence = new String( receivePacket.getData());
                  System.out.println("RECEIVED: " + sentence);
                  InetAddress IPAddress = receivePacket.getAddress();
                  int port = receivePacket.getPort();
                  String servo = br.readLine();
          if(new String(servo).equals("bye")==true)
            break;
                  sendData = servo.getBytes();
                  DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
                  serverSocket.send(sendPacket);
          sendData=null;
               }

      }
}

UDP 中的客户端代码

    import java.io.*;
import java.net.*;

class clientee
{
   public static void main(String args[]) throws Exception
   {
      BufferedReader inFromUser =new BufferedReader(new InputStreamReader(System.in));
      DatagramSocket clientSocket = new DatagramSocket();
      InetAddress IPAddress = InetAddress.getByName("localhost");
      byte[] sendData = new byte[1024];
      byte[] receiveData = new byte[1024];
      while(true)
      {
      String sentence = inFromUser.readLine();
      if(new String(sentence).equals("bye")==true)
    break;
      sendData = sentence.getBytes();
      DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
      clientSocket.send(sendPacket);
      DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
      clientSocket.receive(receivePacket);
      String modifiedSentence = new String(receivePacket.getData());
      System.out.println("FROM SERVER:" + modifiedSentence);
      }

   }
}

服务器输出 This is the output of server

客户的输出 This is the output of client

java networking
2个回答
2
投票

您的代码假设

DatagramPacket.getBytes()
仅返回发送或接收的数据 - 但它返回您在构造 DatagramPacket 时使用的整个数组。当您为多次接收重复使用相同的
sendData
数组时,这会成为一个问题,因为当您接收到的新数据比之前接收到的数据短时,旧数据将保留在数组中。

您的客户端代码必须考虑接收到的数据的长度:

String modifiedSentence = new String(receivePacket.getData(),0, receivePacket.getLength());

您的服务器代码必须执行相同的操作:

String sentence = new String( receivePacket.getData(),0, receivePacket.getLength());

1
投票

不能

flush()
DatagramSocket
DatagramPacket
一起使用。没有什么可以冲洗的。当您调用
send()
时,数据就会被发送。当您拨打
receive()
时,您将收到下一个可用的数据包。

刷新仅适用于在进行

基于流
输出时写入
OutputStream
Writer(或子类型)时。


提示:如果服务器没有看到客户端发送的数据包,反之亦然,则它们可能在传输过程中丢失,或者由于拥塞而被接收方丢弃。 UDP 不提供可靠的消息传送。


但是我确实收到了上次发送的字符串的一部分,您能对此提出任何建议吗?

正如 @nos 所解释的,您的代码的问题之一是您正在发送和接收 1024 字节消息,但只有前几个字节是有用的数据。 当您在问题中说“刷新”时,我怀疑您实际上是指“覆盖”(零字节)。 是的,你可以这样做。 但最好发送 2 个字节或 4 个字节(即有用数据的字节数),而不是发送 1024 个字节,其中大部分为零。

并且...是的...这解释了为什么您收到“oine”作为第二条消息而不是“oi”。

(实际上,您会得到一个由 'o'、'i'、'n'、'e' 组成的 1024 个字符的字符串,后跟 1020

NUL
字节。但是
NUL
是一个非打印 ASCII 控制字符,所以您在显示的输出中看不到它。)

© www.soinside.com 2019 - 2024. All rights reserved.