求教UDP协议发送数据包的大小问题

danielmiaowl 2010-12-21 10:01:26
小弟使用了datagrampacket和datagramsocket2个类实现了基于udp协议的网络通讯,现在想让我每一个数据报的大小都在MTU值之下,大概在548字节,也就是说我发送的每一个数据包都只需要发送一次而不需要底层去拆分和组装。
现在的问题就是我所我给datagrampacket的byte数组大小的最大值取多少合适,我读了下源码,大概知道一个包包装完的大小是byte大小+4个4字节的int变量和一个InetAddress类,但是没办法确定InetAddress类的大小,所以请教下大家,有谁能确定

换句话说就是,假设我有个100字节的byte数组,通过udp协议发送时,实际在网络上传输的数据包大小是多少?
...全文
670 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
danielmiaowl 2010-12-21
  • 打赏
  • 举报
回复
多谢以上,特别是3L的程序很有用,不过,还是没解决我这里的问题

我要做的是想让程序发送的每一个数据包都小于MTU的值,不要让UDP取替我分解和重构数据包
如果网络最大的MTU值是548字节,那么我想让每一个数据包的大小都不超过548字节,但是如果我把数据包的大小设为548字节,肯定是不对的,因为DatagramPacket类和DatagramSocket类又包装了2次548字节的数据,实际流传到网络上的包肯定大于548字节,那么系统应该是拆分成2个,2个包的最大大小应该是2X548字节,效率就降低不少了,所以就想确定一个数据包的最大大小合适?
SZ深呼吸 2010-12-21
  • 打赏
  • 举报
回复
可以运行这段代码试下


import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
*
* @author chencheng
* @version 1.0.0
* @2008-8-12 上午09:16:58
*/
public class ScanMTU {

private String ip;

private String parameter;

public static void main(String args[]) {

ScanMTU mtu = new ScanMTU();

if (args == null || args.length <= 0) {
System.out.println("Please input dest ip.");
return;
} else
mtu.ip = args[0];

try {
mtu.checkIp(mtu.ip);
} catch (Exception e) {
System.err.println(e.getMessage());
return;
}

System.out.println("Test Result: Maximum Transmission Unit(MTU): " + mtu.scan() + " Bytes Free.");

}

private int scan() {
for (int length = 1500; length > 0; length--) {
try {
Process pro = Runtime.getRuntime().exec(setCommand(ip, length));
BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));

int count = 0;
String line = null;
while ((line = buf.readLine()) != null) {
if (!line.equals("")) {
System.out.println(line);
if (count++ == 1) {
if (line.toLowerCase().indexOf("df") == -1)
return length;
break;
}
}
}
buf.close();

} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
return -1;
}

private String setCommand(String ipAddress, int fragSize) {
if (checkForLinux())
parameter = "ping -M do -s " + fragSize;
else if (checkForWindows()) {
parameter = "ping -f -l " + fragSize;
}
return parameter + " " + ipAddress;
}

/**
* 检测输入的IP格式是否正确
*
* @return
* @throws Exception
*/
private void checkIp(String ipAddress) throws Exception {
String regex = "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}";
if (!ipAddress.matches(regex) && !ipAddress.equalsIgnoreCase("localhost")) {
throw new Exception("Input Error!");
}
}

/**
* 检查当前操作系统是否为linux
*
* @return
*/
private boolean checkForLinux() {
String os = System.getProperty("os.name");
return os != null && os.toLowerCase().startsWith("linux") ? true : false;
}

/**
* 检查当前操作系统是否为windows
*
* @return
*/
private boolean checkForWindows() {
String os = System.getProperty("os.name");
return os != null && os.toLowerCase().startsWith("win") ? true : false;
}

dracularking 2010-12-21
  • 打赏
  • 举报
回复
100字节是绰绰有余的,据我所了解的UDP,包括java中构造方法

byte[] buffer = new byte[8192];

DatagramPacket dp = new DatagramPacket(buffer, buffer.length);

对此构造方法而言,它并不在乎缓存能有多大而且会很高兴让你创建一个数兆字节大小的DatagramPacket。
然而,然后底层的原生网络软件就少宽容了,最原始UDP实现不支持超过 8,192 byte/datagram。IPv4的理论极限datagram是65,507字节,而如果一个DatagramPacket对象带有65,507字节大小的缓存的话就可以无损接收任何可能的IPv4 datagram。许多基于UDP的协议如DNS和TFTP会使用每datagram 512字节或更少。NFS的普通使用最大数据大小是8,192字节。几乎所有的你可能碰到的UDP datagrams是8K或更少。实际上,许多操作系统并不支持超过8K数据的UDP datagrams,或截断、或分拆,或丢弃。如果一个datagram因过大而遭到网络截断或丢弃,你的java程序并不会被通知到该问题的存在(UDP毕竟是不可靠协议) 。因此,你不应该创建超过8,192字节的DatagramPacket对象。




pywepe 2010-12-21
  • 打赏
  • 举报
回复
udp协议本身也是有限制的
danielmiaowl 2010-12-21
  • 打赏
  • 举报
回复
抓包了,确定发送的数据包比实际大小大42个字节
dracularking 2010-12-21
  • 打赏
  • 举报
回复
发出去之前的对象大小还不能作为最后网络传输包的实际大小吗?

如果不能,抓下包知道一个大小大概,就差不多能估算出了,不用几次的
dracularking 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 danielmiaowl 的回复:]

多谢以上,特别是3L的程序很有用,不过,还是没解决我这里的问题

我要做的是想让程序发送的每一个数据包都小于MTU的值,不要让UDP取替我分解和重构数据包
如果网络最大的MTU值是548字节,那么我想让每一个数据包的大小都不超过548字节,但是如果我把数据包的大小设为548字节,肯定是不对的,因为DatagramPacket类和DatagramSocket类又包装了2次548字节的数据,实……
[/Quote]
这不是调试下,看一下封装后最后发出去的包大小,应该可以吧
danielmiaowl 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 pauliuyou 的回复:]
一个一个试也没有多少种情况
[/Quote]
关键所是不好试,还得网络抓包。。。。。
pauliuyou 2010-12-21
  • 打赏
  • 举报
回复
一个一个试也没有多少种情况

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧