2014-04-20 2 views
0

UDP를 통해 클라이언트에서 서버로 패킷을 보내려고합니다. 내가 직면하고있는 문제는 마지막 패킷 크기가 우리가 읽고있는 바이트 배열의 크기보다 작 으면 이전 패킷의 중복 된 데이터가 추가된다는 것입니다. 마지막 패킷의 올바른 부분 만 새로운 바이트 배열로 복사 한 다음 보내려고했지만 클라이언트가 어떻게 든 잘못된 패킷 만 전송합니다. 아무도 제가 잘못하고있는 것을 지적 해주십시오. 미리 감사드립니다. 마지막 패킷 크기 우리는 판독 된 바이트 배열의 크기보다 작은 경우UDP 클라이언트 서버 파일 전송

Client.java: 

class client 
{ 
static int serverPort; 
static String filename; 
    public static void main(String args[]) throws SocketException, IOException 
    { 
     int count=0; 
     int MAX_SIZE = 1048; 

     DatagramSocket clientSocket = new DatagramSocket(); 
     InetAddress IpAddress = InetAddress.getByName("localhost"); 

     byte[] sendData = new byte[MAX_SIZE]; 

     String filePath = "C:\\in.txt"; 
     File file = new File(filePath); 
     FileInputStream fis = new FileInputStream(file); 


     int totLength = 0; 

     while((count = fis.read(sendData)) != -1) //calculate total length of file 
     { 
      totLength += count; 
     } 

     System.out.println("Total Length :" + totLength); 

     int noOfPackets = totLength/MAX_SIZE; 
     System.out.println("No of packets : " + noOfPackets); 

     int off = noOfPackets * MAX_SIZE; //calculate offset. it total length of file is 1048 and array size is 1000 den starting position of last packet is 1001. this value is stored in off. 

     int lastPackLen = totLength - off; 
     System.out.println("\nLast packet Length : " + lastPackLen); 

     byte[] lastPack = new byte[lastPackLen-1]; //create new array without redundant information 


     fis.close(); 

     FileInputStream fis1 = new FileInputStream(file); 
     //while((count = fis1.read(sendData)) != -1 && (noOfPackets!=0)) 
     while((count = fis1.read(sendData)) != -1) 
     { 
      if(noOfPackets<=0) 
       break; 
      System.out.println(new String(sendData)); 
      DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IpAddress, 9876); 
      clientSocket.send(sendPacket); 
      System.out.println("========"); 
      System.out.println("last pack sent" + sendPacket); 
     noOfPackets--; 
     } 

     //check 
     System.out.println("\nlast packet\n"); 
     System.out.println(new String(sendData)); 

     lastPack = Arrays.copyOf(sendData, lastPackLen); 

     System.out.println("\nActual last packet\n"); 
     System.out.println(new String(lastPack)); 
       //send the correct packet now. but this packet is not being send. 
     DatagramPacket sendPacket1 = new DatagramPacket(lastPack, lastPack.length, IpAddress,  9876); 
     clientSocket.send(sendPacket1); 
     System.out.println("last pack sent" + sendPacket1); 

    } 
} 

Server.java: 
import java.io.*; 
import java.net.*; 

class server 
{ 
    public static void main(String args[]) throws IOException 
    { 
     DatagramSocket serverSocket = new DatagramSocket(9876); 
     byte[] recData = new byte[1024]; 
     int i =0; 

     FileWriter file = new FileWriter("C:\\Users\\ayushi\\Documents\\Semester 2\\Misc\\setups\\eclipse\\ip_1\\ip_second\\src\\out.txt"); 
     PrintWriter out = new PrintWriter(file); 


     //BufferedOutputStream bos = new BufferedOutputStream(fos); 

     while(true) 
     { 
      //PrintWriter out = new PrintWriter(file); 

      DatagramPacket recPacket = new DatagramPacket(recData, recData.length); 
      serverSocket.receive(recPacket); 
      String line = new String(recPacket.getData()); 
      System.out.println("\n Data: " + line); 
      out.println(line); 
      System.out.println("\nPacket" + ++i + " written to file\n"); 
      out.flush(); 
     } 
    } 
} 

답변

2

이전 패킷으로부터 다음 중복 데이터가 추가되고있다.

아니요. 문제는 첫 번째 패킷의 바이트가 여전히 recData 바이트 배열에 포함되어 있다는 것입니다. 후속 읽기는 바이트 배열의 시작을 두 번째 패킷의 내용으로 덮어 쓰지 만 배열의 나머지는 여전히 첫 번째 패킷의 데이터로 채워집니다.

근본적인 문제는 수신 한 실제 바이트 수를 무시한다는 것입니다. Writer이 아닌 FileOutputStream도 사용해야합니다. 사용해보기 :

class Server 
{ 
    public static void main(String args[]) throws IOException 
    { 
     ... 

     while(true) 
     { 
      DatagramPacket recPacket = new DatagramPacket(recData, recData.length); 
      serverSocket.receive(recPacket); 
      System.out.println("\n Packet length: " + recPacket.getLength()); 
      out.write((recPacket.getData(), 0, recPacket.getLength()); 
      System.out.println("\nPacket" + ++i + " written to file\n"); 
      out.flush(); 
     } 
    } 
} 
+0

고맙습니다. 그것은 효과가 있었다. 그러나 코드에는 사소한 문제가 있습니다. 새 파일에 쓰는 동안 2 3 단어가 복사되지 않습니다. 모든 오프셋과 모든 값을 검사했는데 모든 것을 복사해야하지만 어떻게 든 알아낼 수는 없습니다. –

+0

차이점은 서버와 클라이언트가 보내고받는 바이트 수에 대해 서로 다른 크기를 사용하고 있다는 것입니다. 서버는 1024의 바이트 크기를 사용하고 클라이언트는 1048을 전송합니다. 이렇게하면 서버가 패킷을 수신 할 때마다 "유선으로"24 바이트가 남습니다. 희망이 도움이됩니다. –

+1

또한 데이터 유실에주의해야 할 것이 UDP의 특성입니다. UDP 패킷을 보내면받을 수 있다고 보장 할 수 없습니다. 보장 된 전달이 필요한 경우 UDP가 실행 가능한 옵션이 될 수 없습니다. –