使用高级语言在通过交换机连接的两台计算机之间传输数据

Transferring data between two computers connected with a switch from a high level language

首先我要声明我对网络和整个 OSI 模型知之甚少。

我的目标是使用非托管网络交换机创建一个小型网络(现在是我的笔记本电脑和 raspberry Pi)。在更高层传输(级别 3+)上,我会简单地设置数据包的目标 IP 地址。根据我在维基百科上阅读的内容,网络交换机在数据 link 层运行,这意味着它使用 MAC 地址。

当连接到仅支持 MAC 地址的设备时,如何将数据发送到局域网上的设备。更重要的是,如何从 Java 或 C# 等高级语言中做到这一点?

TL;DR OSI 模型是关于抽象的,编程语言使用操作系统调用来实现这种抽象。 Rasberry Pi 是 运行 一个完整的 OS,它将发送和接收寻址到其分配的 IP 地址的网络数据。您不需要指定 MAC 地址。

您想通过笔记本电脑与 Raspberry Pi 通信。为此,您首先将它们连接到哑交换机,并在连接到哑交换机的物理接口上为两个设备分配同一子网中的 IP 地址。假设你的笔记本电脑的物理以太网连接被分配 10.0.0.1/24 并且 Rasberry Pi 的物理以太网连接被分配 10.0.0.2/24 (如果你不理解我的符号请看 CIDR). IP addresses are Layer 3 constructs. Now your application will use an Operating System socket to create a TCP or UDP connection(see UDP java example here)第 4 层地址(应用端口)。高于第 4 层的所有内容都由您的应用程序处理。

第 2 层及更低层由 OS 处理。当您的应用程序尝试通过套接字发送数据时,操作系统会通过查看目标 IP 地址来确定从哪个物理接口发送数据。此查找使用 OS 路由 Table。假设您有一个正常的路由 table,OS 将选择具有与目标 IP 具有相同子网的 ab IP 的接口。因此,如果您向 10.0.0.2 发送数据,您的 OS 将从 10.0.0.1 发送数据,因为它与 10.0.0 具有相同的子网。现在 OS 已经选择了一个接口,它仍然不知道将第三层 IP 数据包发送到哪个第二层 MAC 地址。 OS 不知道这一点的主要原因是 IP 地址可以更改,但第 2 层 MAC 地址不应该。无论如何,OS 发出一个 ARP 请求,试图获取 IP 地址的 MAC 地址。如果设备连接正确,OS 会获得所需 IP 地址的 MAC 地址,并开始向该 MAC 地址发送数据。开关(智能或哑)确保消息到达所需的 MAC 地址。在接收端,OS接收数据包,并将数据包中的数据发送给绑定到四层地址(应用端口)的套接字。

旁注:使用 RAW 套接字仅将数据发送到 MAC 地址在技术上是可行的,但这非常技术性。

Liam Kelly 的回答提供了对数据发送抽象的深刻见解。我会尽量提供补充信息。

网络切换操作

虽然大多数交换机在数据级别运行,there are some 可以在更高级别执行某些操作:

  • layer 3: Within the confines of the Ethernet physical layer, a layer-3 switch can perform some or all of the functions normally performed by a router.

  • layer 4: [...] capability for network address translation, but then adds some type of load distribution based on TCP sessions.

  • layer 7: [...] distribute the load based on uniform resource locators (URLs), or by using some installation-specific technique to recognize application-level transactions.

RAW 套接字使用

如前所述,这些需要相当高级的编程技能。出于安全考虑,它们在现代 Windows 操作系统 (source) 的非服务器版本中也受到严格限制:

  • TCP data cannot be sent over raw sockets.
  • UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).
  • A call to the bind function with a raw socket for the IPPROTO_TCP protocol is not allowed.

建议

如果 .NET 对您来说是一个可行的选择,我会 Pcap.Net 试一试,因为它允许使用高级编程(包括 LINQ)在数据包级别进行各种操作。