繁体   English   中英

如何在 Java 中使用 UDP 发送文件

[英]How to Send Files using UDP in Java

我有一个使用 java 进行套接字编程的项目。 我们必须编写客户端和服务器代码来传输文件,代码在编译时没有显示错误但不执行,当我输入文件名时它会冻结。

我知道 UDP 不是传输文件的好主意,但我必须将它作为一个项目来做我的代码是:

客户代码

import java.io.*;
import java.net.*;
import java.util.*;
public class Client
{
static InetAddress dest;
public static void main(String [] args) throws Exception
{

    DatagramSocket clskt = new DatagramSocket();
    Scanner input = new Scanner (System.in);
    int port =input.nextInt();
    System.out.println("Enter Destination Host name");
    String hostname=input.next();
    dest.getByName(hostname);
    int packetcount=0;
    System.out.println("Enter The path of the file you want to send");
    String path = input.next(); 
    File initialFile = new File(path);
            FileInputStream targetStream = new FileInputStream(initialFile);
    int filesize=targetStream.available();
    //int neededpackets =(int)Math.ceil((double)(size/1024));
     byte [] data= new byte[1024];
     // counting bytes
     for (int i=0;i<1024;i++)
     {
         data[i]=(byte)targetStream.read();
     }
     //create a packet
    DatagramPacket clpkt=new DatagramPacket(data,data.length,dest,port);
    packetcount++;
    clskt.send(clpkt);
    if(packetcount >neededpackets)
        clskt.close();
   }

 }

服务器代码

 import java.io.*;
 import java.net.*;
 import java.util.*;

 class Server1
   {
public static void main(String args[])throws Exception
{
    System.out.println("Enter Port number !!!");
    Scanner input = new Scanner(System.in);
    int SPort = input.nextInt();
    DatagramSocket srvskt = new DatagramSocket(SPort);
    byte[] data =new byte[1024];
    System.out.println("Enter a full file name to save data to it ?");
    String path = input.next();
    System.out.println("file : "+path+" will be created.");
    FileOutputStream  FOS = new FileOutputStream(path);
    DatagramPacket srvpkt = new DatagramPacket(data,1024);
    System.out.println("listening to Port: "+SPort);
    int Packetcounter=0;//packet counter
    while(true)
       {
           srvskt.receive(srvpkt);
           Packetcounter++;
           String words = new String(srvpkt.getData());
           InetAddress ip= srvpkt.getAddress();
           int port = srvpkt.getPort();
           System.out.println("Packet # :"+Packetcounter+"
            Received from Host / Port: "+ip+" / "+port);
           FOS.write(data);
           //out16.flush();
           if (Packetcounter >=100)
                 break;

      }
    FOS.close();//releasing file.
    System.out.println("Data has been written to the file !");
  }
}

在此先感谢大家。

我在客户端第一眼看到的是,您尝试使用的dest字段永远不会被单元化,它仍然为空。 您应该编写dest = InetAddress.getByName(anArgument)以便dest获得新 InetAddress 实例的值。 因此,当您的代码可编译时,您很可能会收到 Null 指针异常。 现在是不是,只要neededpackets没有定义。

这是我提出的一个快速示例。 它使用DatagramSocket连接,我认为这是唯一的方法。

public class BroadcastTest
{
   private static final int RANDOM_PORT = 4444;

   public static void main( String[] args )
           throws Exception
   {
      InetAddress addr = InetAddress.getByName( "127.0.0.1" );
      DatagramSocket dsock = new DatagramSocket();
      byte[] send = "Hello World".getBytes( "UTF-8" );
      DatagramPacket data = new DatagramPacket( send, send.length, addr, RANDOM_PORT );
      dsock.send( data );
   }
}

这是服务器代码。 这些似乎有效,但我还没有彻底测试它们!

class Server {
   private static final int RANDOM_PORT = 4444;

   public static void main(String[] args) {
      try {
         DatagramSocket dsock = new DatagramSocket( RANDOM_PORT );
         DatagramPacket data = new DatagramPacket( new byte[ 64*1024 ], 64*1024 );
         dsock.receive( data );
         System.out.println( new String( data.getData(), 0, 
                 data.getLength(), "UTF-8" ) );
      } catch( SocketException ex ) {
         Logger.getLogger(Server.class.getName() ).
                 log( Level.SEVERE, null, ex );
      } catch( IOException ex ) {
         Logger.getLogger(Server.class.getName() ).
                 log( Level.SEVERE, null, ex );
      }
   }
}

希望这对您或将来的某人有所帮助。 我创建了一个 UDP 库来使 UDP 类似于 TCP。 这是一种更可靠的 UDP 传输形式。

https://github.com/DrBrad/BetterUDPSocket

这是在库中发送/接收文件的示例: https : //github.com/DrBrad/BetterUDPSocket/blob/main/src/unet/uncentralized/betterudpsocket/Samples/FileTransfer.java

实现这一点的方法是创建一个新协议。 例如

+----+------+-------+------+
| ID | CODE | ORDER | DATA |
+----+------+-------+------+

在我的库中,我使用 UUID 作为 ID,这是一个 16 字节的标识符,以确保数据包不会在流中混淆。 例如,假设 Alice 想同时发送 1.JPG 和 2.JPG。 我们不能混淆这些数据包。

我创建了一些可能有用的代码:

  1. [0x00] DATA - 用于发送数据
  2. [0x01] SUCCESS ACK - 用于在收到数据时通知发送方我们已收到数据
  3. [0x02] FAIL ACK - 数据乱序,这将使发送方发送最后一个数据包
  4. [0x03] KEEP ALIVE - 每 25 秒发送一个小数据包,以防止 NAT 关闭端口
  5. [0x05] CLOSE - 告诉客户端/服务器我们已经关闭了连接

最后对于 ORDER 我们必须确保在发送文件时所有数据都是有序的,很可能在处理数据时接收方可能没有得到最后一个数据包。 这可能会导致数据包乱序。 为了解决这个问题,我们让客户端和服务器对成功发送/接收的每个数据包进行计数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM