Java多播发送器+;接受者

Java多播发送器+;接受者,java,sockets,multicast,Java,Sockets,Multicast,我的问题很容易解释。我有一个多播发送器和一个多播接收器。我试图发送一个8MB的大文件。它应该分成1024字节的包和4字节的头。发送正常,但接收器在5000位置取消接收,有时在2000或3000位置取消接收。我不知道为什么它没有接收到所有元素 发件人: import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.DatagramPacket; import java

我的问题很容易解释。我有一个多播发送器和一个多播接收器。我试图发送一个8MB的大文件。它应该分成1024字节的包和4字节的头。发送正常,但接收器在5000位置取消接收,有时在2000或3000位置取消接收。我不知道为什么它没有接收到所有元素

发件人:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;

public class Sender extends Thread{

protected static MulticastSocket socket = null;
public int QuoteCount = 0;
public int Time_Interval = 6000;
public static FileInputStream in;
final static int split_size = 1028 ;

public static void main(String[] args) throws IOException{
    // args 0 => path
    // args1=> ip multicast
    // args2 => networkinterface ip
    // args3 => port 
    // args4 => ttl
    //socket = new MulticastSocket(444);
    InetAddress ip_address_group = InetAddress.getByName(args[1]);
    System.out.println("Wait 4 clients to connect...");
    File file=new File(args[0]);

    InetSocketAddress address = new InetSocketAddress(args[1],Integer.parseInt(args[3]));
    MulticastSocket socket = new MulticastSocket(new InetSocketAddress(args[2], Integer.parseInt(args[3])));
    socket.connect(address);
    socket.setTimeToLive(Integer.parseInt(args[4]));

    MD5 md5 = new MD5();
    try {
        System.out.println("MD5 vom File: "+md5.getFileMD5(args[0]));
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    // Filesize package
    int filesize = (int)file.length();

    double anzpak=(filesize/1028); // anzahl pakete
    double diagrammgrenze=(80/anzpak); // wieviele stricherl setzt ein paket
    double strikecount=0;
    System.out.println("DIAGR: "+diagrammgrenze +" Anzpak: "+anzpak);

    byte[] firstpack=new byte[4];
    int2bytearr(filesize,firstpack);
    DatagramPacket firsttosend=new DatagramPacket(firstpack,firstpack.length,ip_address_group, Integer.parseInt(args[3]));
    socket.send(firsttosend);

    // Rest of packages
    in = new FileInputStream(file);

    byte[] data = new byte[split_size];
    int numbytes = 0;
    int seqnr = 0;
    int sentbytes=0;

    try {
        while((numbytes = in.read(data)) != -1){
            // Generate 4 byte long seqnr:
            seqnr++;
            strikecount+=diagrammgrenze;
            if(strikecount>=1){
                for(int i=0;i<(int)strikecount;i++){
                    System.out.print("|");
                    strikecount--;
                }
            }

            byte[] dataseq = new byte[4];
            int2bytearr(seqnr,dataseq);
            sentbytes+=numbytes;

            // DATA PLUS SEQNR Generation 
            byte[] seqplusdata = new byte[dataseq.length + data.length];
            System.arraycopy(dataseq, 0, seqplusdata, 0, dataseq.length);
            System.arraycopy(data, 0, seqplusdata, dataseq.length, data.length);

            // Data Plus Seqnr Sending
            DatagramPacket tosend=new DatagramPacket(seqplusdata,seqplusdata.length);
            socket.send(tosend);
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println("\nTosend filesize: "+filesize);
    System.out.println("Sent bytes: "+sentbytes);
    //in.close();
    socket.close();
}

public static void int2bytearr(int number,byte[] data){
    for (int i = 0; i < 4; ++i) {
        int shift = i << 3; // i * 8
        data[3-i] = (byte)((number & (0xff << shift)) >>> shift);
    }
}

}
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.net.DatagramPacket;
导入java.net.InetAddress;
导入java.net.InetSocketAddress;
导入java.net.MulticastSocket;
公共类发送器扩展线程{
受保护的静态多播套接字=null;
公共整数QuoteCount=0;
公共整数时间间隔=6000;
中的公共静态文件输入流;
最终静态整数分割大小=1028;
公共静态void main(字符串[]args)引发IOException{
//args 0=>path
//args1=>ip多播
//args2=>网络接口ip
//args3=>端口
//args4=>ttl
//插座=新的多播插座(444);
InetAddress ip_address_group=InetAddress.getByName(args[1]);
System.out.println(“等待4个客户端连接…”);
File File=新文件(args[0]);
InetSocketAddress address=新的InetSocketAddress(args[1],Integer.parseInt(args[3]);
MulticastSocket=新的MulticastSocket(新的InetSocketAddress(args[2],Integer.parseInt(args[3]));
socket.connect(地址);
setTimeToLive(Integer.parseInt(args[4]);
MD5 MD5=新的MD5();
试一试{
System.out.println(“MD5 vom文件:+MD5.getFileMD5(args[0]));
}捕获(异常e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}
//文件大小包
int filesize=(int)file.length();
双anzpak=(filesize/1028);//anzahl pakete
双图GRENZE=(80/anzpak);//wieviele stricherl setzt ein paket
双删除计数=0;
System.out.println(“DIAGR:+diagrammgrenze+”Anzpak:+Anzpak”);
字节[]firstpack=新字节[4];
int2bytarr(文件大小,第一个包);
datagrampacketfirsttosend=新的DatagramPacket(firstpack,firstpack.length,ip_地址_组,Integer.parseInt(args[3]);
socket.send(firsttosend);
//其余的包裹
in=新文件输入流(文件);
字节[]数据=新字节[拆分大小];
int numbytes=0;
int-seqnr=0;
int sentbytes=0;
试一试{
而((numbytes=in.read(data))!=-1){
//生成4字节长的序列号:
seqnr++;
删除计数+=图表长度;
如果(删除次数>=1){
对于(int i=0;i移位);
}
}
}
接收人:

import java.io.IOException;
import java.net.MulticastSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;

public class Empfaenger extends Thread{

public static void main(String[] args) throws IOException{
    Empfaenger empfaenger = new Empfaenger();
    empfaenger.start();
}

@SuppressWarnings("resource")
public void run(){
    try{

        //Create socket
        MulticastSocket socket = new MulticastSocket(12345);

        //Connect to server (must be multicast)
        InetAddress IP_Adress = InetAddress.getByName("228.5.6.7");
        socket.joinGroup(IP_Adress);

        DatagramPacket packet;
        int pcount=0;

        // firstpack for getting filesize package
        byte[] firstpack = new byte[4];
        DatagramPacket firstpacket=new DatagramPacket(firstpack,firstpack.length);
        socket.receive(firstpacket);
        int filesize=makeintfrombyte(firstpack);
        System.out.println("Empfaenger filesize: " + filesize);

        double anzpak=(filesize/1028); // anzahl pakete
        double diagrammgrenze=(80/anzpak); // wieviele stricherl setzt ein paket
        double strikecount=0;

        for(int i=0;i<anzpak;i++){
            System.out.println(pcount + "< "+anzpak);

            strikecount+=diagrammgrenze;
            if(strikecount>=1){
                while(strikecount>=1){
                    System.out.print("|");
                    strikecount--;
                }
            }

            byte[] buf = new byte[1028];
            packet = new DatagramPacket(buf, buf.length);
            socket.receive(packet);
            pcount++;
            //System.out.println("SeqNr. in Bytes: "+buf[0]+"|"+buf[1]+"|" +buf[2]+"|" +buf[3]+"|" + pcount);
        }
        //socket.leaveGroup(IP_Adress);
        //socket.close();

    }catch ( IOException X) {System.out.println(X);}
}

public int makeintfrombyte(byte[] b){
    return b[0] << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff);
}

}
import java.io.IOException;
导入java.net.MulticastSocket;
导入java.net.DatagramPacket;
导入java.net.InetAddress;
公共类Empfaenger扩展线程{
公共静态void main(字符串[]args)引发IOException{
Empfaenger Empfaenger=新Empfaenger();
empfaenger.start();
}
@抑制警告(“资源”)
公开募捐{
试一试{
//创建套接字
MulticastSocket=新的MulticastSocket(12345);
//连接到服务器(必须是多播)
InetAddress IP_address=InetAddress.getByName(“228.5.6.7”);
socket.joinGroup(IP_地址);
数据包;
int pcount=0;
//获取文件大小包的firstpack
字节[]firstpack=新字节[4];
DatagramPacket firstpacket=新的DatagramPacket(firstpack,firstpack.length);
socket.receive(第一个数据包);
int filesize=makeintfrombyte(第一个包);
System.out.println(“Empfaenger filesize:+filesize”);
双anzpak=(filesize/1028);//anzahl pakete
双图GRENZE=(80/anzpak);//wieviele stricherl setzt ein paket
双删除计数=0;
对于(int i=0;i


<>编辑:如果让发件人休眠(长)1,它就不能让发送者睡觉:(

数据报没有保证传递,所以它不是一个理想的传输文件的协议。你可能想考虑一个可靠的多播协议。”
最后,如果您的发送速率高于接收速率,您最终将丢弃数据包。事实上,即使速率非常相似,接收端的任何临时速度(例如调度程序、垃圾收集器等)都会减慢可以开始删除。通过调用增加基础网络缓冲区大小将给您一些余量,并大大改善行为。默认值通常为128K,至少在UX系统上是这样;尝试将其设置为几MB。

receivebuffersize以字节为单位?如果我将其设置为450kB,则适用于100MB以下的文件。但是如果变得更大,它又损坏了软件包:/@StefanSprenger我会毫不犹豫地将其设置得更高一点,例如4MB。这样你就可以优化接收应用程序的性能。在非常高的速率下,甚至每个数据包上的System.out.println都会开始影响性能。另外,为什么不在循环之前只分配一次buf呢?