You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已知两端本地及公网IP,跨网络发送数据包(Scapy/Python Socket)

Sending Packets Between Computers on Different Networks (Socket & Scapy)

Great question! Sending packets across separate networks means dealing with NAT (Network Address Translation) — that thing your home router uses to let multiple devices share a single public IP. Let's walk through how to pull this off with both Python's socket module and Scapy, including the critical setup you'll need first.

First, The Critical Pre-Requisite: Port Forwarding

Before writing any code, you must configure port forwarding on the receiving network's router. Here's why:

  • When a packet hits the receiver's public IP, the router has no idea which local device to send it to. Port forwarding tells the router: "Any traffic coming in on port X should go to the receiver's local IP (e.g., 192.168.1.100) on port Y."

Make sure you set this up first — without it, your packets will just get dropped at the receiver's router.


Method 1: Using Python's Built-in socket Module

The socket module is perfect for sending application-layer data (like TCP/UDP) across networks. It handles most low-level routing automatically, as long as port forwarding is in place.

Example: Sending UDP Packets

UDP is connectionless, so it's simpler for quick testing:

import socket

# Sender's details (you can omit local IP/port if you want the OS to pick them)
sender_local_ip = "192.168.0.5"  # Replace with your local IP
sender_local_port = 12345

# Receiver's details
receiver_public_ip = "203.0.113.45"  # Replace with receiver's public IP
receiver_forwarded_port = 54321  # The port you forwarded on their router

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Optional: Bind to the sender's specific local IP/port
sock.bind((sender_local_ip, sender_local_port))

# Send data
message = b"Hello from the other network!"
sock.sendto(message, (receiver_public_ip, receiver_forwarded_port))

print(f"Sent packet to {receiver_public_ip}:{receiver_forwarded_port}")

# Close the socket
sock.close()

Example: Sending TCP Packets

TCP is connection-oriented, so you'll need a listener on the receiver's end first:

Receiver Side (Local Network)

import socket

receiver_local_ip = "192.168.1.100"
receiver_local_port = 54321

# Create TCP socket
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.bind((receiver_local_ip, receiver_local_port))
server_sock.listen(1)

print(f"Listening for connections on {receiver_local_ip}:{receiver_local_port}")
conn, addr = server_sock.accept()
print(f"Connected by {addr}")

while True:
    data = conn.recv(1024)
    if not data:
        break
    print(f"Received: {data.decode()}")
    conn.sendall(b"Message received!")

conn.close()

Sender Side

import socket

sender_local_ip = "192.168.0.5"
sender_local_port = 12345

receiver_public_ip = "203.0.113.45"
receiver_forwarded_port = 54321  # Matches the port forwarded to receiver's local port

# Create TCP socket
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.bind((sender_local_ip, sender_local_port))  # Optional

# Connect to receiver's public IP/forwarded port
client_sock.connect((receiver_public_ip, receiver_forwarded_port))

# Send data
message = b"Hello via TCP!"
client_sock.sendall(message)

# Receive response
response = client_sock.recv(1024)
print(f"Received response: {response.decode()}")

client_sock.close()

Method 2: Using Scapy

Scapy lets you craft raw packets at the network/transport layer, giving you full control over every field. Note that you'll need root/sudo privileges to send raw packets.

Example: Sending a Raw UDP Packet

from scapy.all import IP, UDP, send

# Sender's details
sender_local_ip = "192.168.0.5"
sender_public_ip = "198.51.100.20"  # Your network's public IP (Scapy might auto-detect this, but you can specify)

# Receiver's details
receiver_public_ip = "203.0.113.45"
receiver_forwarded_port = 54321

# Craft the packet
packet = IP(src=sender_local_ip, dst=receiver_public_ip) / UDP(sport=12345, dport=receiver_forwarded_port) / b"Raw UDP packet from Scapy!"

# Send the packet (use sudo on Linux/macOS)
send(packet, verbose=1)

Important Notes for Scapy:

  • NAT Handling: Scapy will handle NAT on your sender's router automatically (your router will replace the source local IP with your public IP in the outgoing packet). The receiver's router needs port forwarding to send the packet to their local device.
  • Permissions: On Linux/macOS, run the script with sudo — raw packet sending requires root access. On Windows, you might need to install WinPcap/Npcap and run the command prompt as administrator.
  • TCP Packets: If you want to send TCP packets, you'll need to handle the 3-way handshake (SYN, SYN-ACK, ACK) manually, or use Scapy's sendp with more advanced logic. For most use cases, the socket module is easier for TCP.

Key Things to Remember

  • Firewalls: Make sure both sender and receiver have firewalls allowing traffic on the ports you're using (e.g., 54321 in the examples).
  • Dynamic Public IPs: If either network has a dynamic public IP (common with home ISPs), you'll need a dynamic DNS service to track changes.
  • NAT Traversal: For scenarios where port forwarding isn't possible (e.g., both devices are behind strict NAT), you might need a relay server (like a VPN or a custom middleman server) to route traffic between them.

内容的提问来源于stack exchange,提问作者Liron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:18:06