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

解决方案 »

  1.   

    udp协议本身也是有限制的 
      

  2.   

    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对象。
      

  3.   

    可以运行这段代码试下
    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;
    }
      

  4.   

    多谢以上,特别是3L的程序很有用,不过,还是没解决我这里的问题我要做的是想让程序发送的每一个数据包都小于MTU的值,不要让UDP取替我分解和重构数据包
    如果网络最大的MTU值是548字节,那么我想让每一个数据包的大小都不超过548字节,但是如果我把数据包的大小设为548字节,肯定是不对的,因为DatagramPacket类和DatagramSocket类又包装了2次548字节的数据,实际流传到网络上的包肯定大于548字节,那么系统应该是拆分成2个,2个包的最大大小应该是2X548字节,效率就降低不少了,所以就想确定一个数据包的最大大小合适?