2014-04-20 56 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字节数组中。随后的读取将用第二个数据包的内容覆盖字节数组的开头,但数组的其余部分仍然填充来自第一个数据包的数据。

潜在的问题是,您忽略了接收到的实际字节数。您还应该使用FileOutputStream,而不是Writer。试试这个:

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不会是一个可行的选择。 –