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);
这没有什么区别。
下面是一些示例代码,显示了从字符串的字节构造数据报包,发送它以及重构字符串。
请注意,接收数据包的缓冲区被创建得比最终收到的消息大得多。这是必要的,因为如果接收到大于缓冲区的消息,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的用在这里,因为你可以直接将String
到byte[]
,然后再返回。
我提出了建议的编辑。没有成功。我应该注意到,我正在线程服务器端。不知道这将如何改变。谢谢您的帮助! – mjr
@mjr在我们可以进一步帮助你之前,你将不得不发布更多的代码(尽量减少它仍然存在的问题)。我已经指出你的客户端正在使用'ByteArrayInputStream'和'DataInputStream',但是在你的服务器代码中没有使用这样的对等物;一个'DataOutputStream'应该被用作DataInputStream的来源等。我已经指出,如果你没有指定足够大的缓冲区,UDP数据包将丢失数据。我给了你一个工作示例来与你的代码进行比较。没有看到更多的代码,我们所能做的只是猜测。 – AJNeufeld
我修好了。问题在于我没有从客户端更改我的原始buf,因此只能收到与发送的原始字符串的长度一样多的字母。 – mjr
目前看起来不错。如果你的输入中有任何换行符,''readLine()''会把它搞乱...... – f1sh
'DataInputStream'应该和'DataOutputStream'匹配。你的服务器代码只显示'data.getBytes()',不知道'data'是什么,或者它是如何产生的。 'DataInputStream#readLine()'已弃用。 – AJNeufeld
你可能会尝试使用'new String(packet.getData(),StandardCharsets.UTF_8)'''将字节转换为字符串。我没有看到在这里使用'DataInputStream'的原因。可能会导致问题,因为@ f1sh指出。 –