我正在尝试使用基本的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);
}
}
}
您的代码假设
DatagramPacket.getBytes()
仅返回发送或接收的数据 - 但它返回您在构造 DatagramPacket 时使用的整个数组。当您为多次接收重复使用相同的 sendData
数组时,这会成为一个问题,因为当您接收到的新数据比之前接收到的数据短时,旧数据将保留在数组中。
您的客户端代码必须考虑接收到的数据的长度:
String modifiedSentence = new String(receivePacket.getData(),0, receivePacket.getLength());
您的服务器代码必须执行相同的操作:
String sentence = new String( receivePacket.getData(),0, receivePacket.getLength());
您不能将
flush()
与DatagramSocket
或DatagramPacket
一起使用。没有什么可以冲洗的。当您调用 send()
时,数据就会被发送。当您拨打 receive()
时,您将收到下一个可用的数据包。
刷新仅适用于在进行
基于流输出时写入
OutputStream
或Writer
(或子类型)时。
提示:如果服务器没有看到客户端发送的数据包,反之亦然,则它们可能在传输过程中丢失,或者由于拥塞而被接收方丢弃。 UDP 不提供可靠的消息传送。
但是我确实收到了上次发送的字符串的一部分,您能对此提出任何建议吗?
正如 @nos 所解释的,您的代码的问题之一是您正在发送和接收 1024 字节消息,但只有前几个字节是有用的数据。 当您在问题中说“刷新”时,我怀疑您实际上是指“覆盖”(零字节)。 是的,你可以这样做。 但最好发送 2 个字节或 4 个字节(即有用数据的字节数),而不是发送 1024 个字节,其中大部分为零。
并且...是的...这解释了为什么您收到“oine”作为第二条消息而不是“oi”。
(实际上,您会得到一个由 'o'、'i'、'n'、'e' 组成的 1024 个字符的字符串,后跟 1020
NUL
字节。但是 NUL
是一个非打印 ASCII 控制字符,所以您在显示的输出中看不到它。)