【问题标题】:Creating a network packet without using Socket class不使用 Socket 类创建网络数据包
【发布时间】:2014-01-06 21:08:18
【问题描述】:

我正在尝试对将发送方 IP 地址、目标 IP 地址、发送方端口、目标端口和有效负载数据组合在一起的网络数据包进行编码/解码。

我一直在阅读执行此操作的不同方法,并且到处都建议使用 Socket 类 - 但是,我们不能在我们的程序中使用像这样的真实网络类,因为它只是一个没有真实网络组件的模拟应用程序.

我很困惑如何在不使用 DatagramPacketDatagramSocket 之类的类的情况下创建网络数据包。有效载荷数据为byte[] 形式,IP 地址为InetAddress。我假设我可能不得不使用某种ByteArrayOutputStream 将所有这些元素组合成一个byte[] 类型的网络数据包。

任何关于我如何做到这一点的建议将不胜感激。

【问题讨论】:

  • 套接字是通过我相信的操作系统处理的。 Java 库只是与操作系统交互。我什至不认为 Windows 允许原始数据包访问。也就是说,有些数据包它甚至不让你发送
  • 如果数据无处可去,您肯定只想将其存储在byte[] 中并完成处理?
  • 这正是我想要做的,但我对如何将发送/接收 IP 地址、发送/接收端口号和字节 [] 中的有效负载组合在一起感到困惑字节[].

标签: java sockets networking packets


【解决方案1】:

您的用例令人困惑。您正在创建一个网络应用程序,但您永远不会将您的应用程序放在网络上?这对我来说毫无意义。

在 Java 中,SocketFactory 创建 Sockets (http://docs.oracle.com/javase/7/docs/api/javax/net/SocketFactory.html)。您可以实现自己的 SocketFactory 来生成 Socket 的自定义子类,以创建您需要的所有非网络 Socket 东西。但是,如果没有实际的网络层,我不知道如何让这些非网络套接字进行通信,以便您可以测试诸如“服务器是否收到我发送的数据包”之类的东西。

此外,我认为您不需要一个实际的网络来做 Socket 的事情。 localhost 环回用于此目的。

我想我只是被你的问题弄糊涂了。

【讨论】:

  • 对不起,我想我在解释我的问题方面做得不好。该程序是计算机网络的模拟。有一个“计算机”对象,一个表示物理以太网端口的“交换机端口”对象等。我基本上需要使用这个网络数据包将消息从一个“计算机 A”对象发送到一个“计算机 B”对象,其中包括以上信息。
  • 所以听起来 Socket 在这里是无关紧要的,你被要求提出一个包含源地址、目标地址和 byte[] 有效负载的抽象。忘记套接字并构建它。那就是,什么,2个班;地址(字符串主机名,int 端口)和数据包(地址源,地址目标,字节 [] 有效负载)。我的建议,不要让这件事变得更难。
【解决方案2】:

我想你只是想创建/编辑一个字节[]或读取一个字节[]

因为数据报包只不过是一个字节[]!!!

你可能会想到这样的方法:

byte[] package; //it sould be at least 20 byte and conform to TCP/IP IPv4

public static byte[] getSourceIp(byte[] package){
    byte[] sourceIp = new byte[4];
    //System.arraycopy(package, 96, sourceIp, 4); //way shorter
    for (int i = 0; i < 4; i ++){
        sourceIp [i] = package[i+12]; //12=offset for source ip @ipv4
    }
    return sourceIp;
}

public static void setSourceIp(byte[] sourceIp , byte[] package){
    for (int i = 0; i < 4; i ++){
        package[i+12] = sourceIp[i];  //12=offset for source ip @ipv4
    }
}

让我们断言你的 byte[] 包符合 TCP/IP IPv4 协议并且至少 160 位(20 字节)长... http://en.wikipedia.org/wiki/IPv4

【讨论】:

    【解决方案3】:

    您可以使用 DatagramPacket。它对网络没有任何作用。

    但在我看来,您应该在这里滚动您自己的数据包类。

    【讨论】:

    • 只是一个模拟程序。 OP似乎说他们不能使用DatagramPacket
    • 即使与外部世界没有真正的联系,模拟也可以指向自己。
    • 指令有点含糊,只是说我不能使用任何“真正的”Java 网络类。我知道这包括 Socket 类,但可能不包括 DatagramPacket 类
    • @SotiriosDelimanolis No. OP 说“没有真正的网络组件”。他得出错误的结论,因此他不能使用DatagramPacket。我在纠正他。他自己的评论也同意。
    • 我没有投反对票,但您应该在答案中详细说明所有这些内容。
    猜你喜欢
    • 2012-11-17
    • 2012-03-19
    • 2022-08-22
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 2016-10-11
    • 1970-01-01
    相关资源
    最近更新 更多