2013-12-11 1 views
2

내 문제는 설명하기 쉽습니다. 멀티 캐스트 발신자와 멀티 캐스트 수신자가 있습니다. 나는 8MB 큰 파일을 보내려고했다. 1024 바이트 패키지 + 4 바이트 헤더로 분할되어야합니다. 전송은 괜찮지 만 수신자는 때로는 2000 또는 3000의 위치 5000에서 수신을 취소합니다. 왜 모든 요소를 ​​수신하지 못하는지 모르겠습니다.Java 멀티 캐스트 보낸 사람 + 수신기

보낸 사람 :

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); 
    } 
} 

} 

수신기는

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); 
} 

} 
다음

수신기와 하나 개의 보낸 사람] http://i.stack.imgur.com/UblCa.jpg

편집 할 수의 샘플 출력 상 : 우리를 위해 보낸 사람의 수면을 할 경우 (long) 1.0 작동하지만 송신자가 잠자 게하는 것은 의미가 아닙니다 : (

답변

3

데이터 그램은 배달 보장이 없으므로 파일 전송에 이상적인 프로토콜이 아닙니다. 대신 신뢰할 수있는 멀티 캐스트 프로토콜을 고려할 수 있습니다.

마지막으로 전송 속도가 수신 속도보다 높으면 결국 패킷이 삭제됩니다. 실제로 요금이 매우 유사하더라도 수신 측에서 일시적으로 느려지는 경우 (예 : 스케줄러, 가비지 수집기 등 ...) 이탈이 시작될 수 있습니다. setReceiveBufferSize을 호출하여 기본 네트워크 버퍼 크기를 늘리면 약간의 여유가 생겨 동작이 크게 향상됩니다. 기본값은 대개 UX 시스템에서 128K입니다. 몇 MB로 설정해보십시오.

+0

receivebuffersize는 바이트 단위입니까? 450kB로 설정하면 100MB 미만의 파일에서도 작동합니다. 하지만 그들이 커지면 패키지가 손상됩니다./ –

+0

@StefanSprenger 나는 조금 더 높게 설정하는 것을 망설이지 않을 것입니다. 4MB. 그런 다음 수신하는 앱의 성능을 최적화 할 수 있습니다. 매우 빠른 속도로, 모든 패킷의 System.out.println조차도 성능에 영향을 줄 수 있습니다. 또한 루프 앞에서 buf를 한 번만 할당하면됩니까? 귀하의 도움을 위해서 – mac

+0

kk thx –

관련 문제