reb*_*rid 0 python sockets client-server raw-sockets
我想在 Python 中实现一个 RAW 套接字,然后将数据从客户端发送到服务器。
与普通套接字不同,我尝试使用以下定义
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
Run Code Online (Sandbox Code Playgroud)
但命令为
s.listen(1), s.connect()
Run Code Online (Sandbox Code Playgroud)
不工作。我不知道如何对 Client.py 和 Server.py 进行编程。有人能帮我吗?
那是因为原始套接字根本不使用以太网/TCP/IP 库。这是一个 RAW 套接字,您负责发送的任何数据。您还负责通过发送正确的 SYN/ACK 顺序连接到对等方。
传统套接字是一个“抽象”层,供您发送负载(数据)。这意味着您将套接字连接到目的地,您告诉套接字要发送的数据,假设您使用的是基于 TCP 的套接字,您的数据将预先带有与 TCP 协议和版本相对应的标头,并且您的数据可能会根据以下内容进行分段您尝试推送多少数据。
所有这些都通过传统套接字自动发生。
这是 TCP 标头的大致样子(脱离上下文,但它会给您一个想法):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)
请注意,数据是您通常所做的,但是在使用 RAW 套接字时,您需要将所有这些信息块发送到您的以太网电缆上。
如果有人没有打败我,我可以在今晚晚些时候发布一些代码,但这是一个很好的简短用法示例:如何在 Python 中使用原始套接字?
您需要构建一个以太网标头和一个 TCP 标头,并根据 RFC 标准将您的数据添加到其中(这可能是一个很好的起点:https : //tools.ietf.org/html/rfc793)。然后您需要“简单地”将其发送到您的“套接字”。RAW 套接字没有任何魔法,您可以使用源地址+目标地址构建标头,然后将有效负载发送到电缆上,希望您正确构建了数据包。
socket.accept()- 此函数用于传统套接字“存储”会话信息(源:端口 -> 目标:端口)。此函数从传入连接尝试的缓冲队列中获取客户端并“激活”它们。这不适用于原始套接字,原因是普通套接字的抽象层再次不存在。您的 RAW 套接字将侦听任何传入数据(而不是连接),这意味着您负责首先接收一个SYN数据包,您需要使用一个数据包进行响应SYN-ACK,您将在其中收到最终的ACK. 此时,您可以使用正确的信息(源端口等)在你们之间发送数据。
这是普通套接字中提供的抽象层的良好(ASCII)流程图:
+---------+ ---------\ active OPEN
| CLOSED | \ -----------
+---------+<---------\ \ create TCB
| ^ \ \ snd SYN
passive OPEN | | CLOSE \ \
------------ | | ---------- \ \
create TCB | | delete TCB \ \
V | \ \
+---------+ CLOSE | \
| LISTEN | ---------- | |
+---------+ delete TCB | |
rcv SYN | | SEND | |
----------- | | ------- | V
+---------+ snd SYN,ACK / \ snd SYN +---------+
| |<----------------- ------------------>| |
| SYN | rcv SYN | SYN |
| RCVD |<-----------------------------------------------| SENT |
| | snd ACK | |
| |------------------ -------------------| |
+---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+
| -------------- | | -----------
| x | | snd ACK
| V V
| CLOSE +---------+
| ------- | ESTAB |
| snd FIN +---------+
| CLOSE | | rcv FIN
V ------- | | -------
+---------+ snd FIN / \ snd ACK +---------+
| FIN |<----------------- ------------------>| CLOSE |
| WAIT-1 |------------------ | WAIT |
+---------+ rcv FIN \ +---------+
| rcv ACK of FIN ------- | CLOSE |
| -------------- snd ACK | ------- |
V x V snd FIN V
+---------+ +---------+ +---------+
|FINWAIT-2| | CLOSING | | LAST-ACK|
+---------+ +---------+ +---------+
| rcv ACK of FIN | rcv ACK of FIN |
| rcv FIN -------------- | Timeout=2MSL -------------- |
| ------- x V ------------ x V
\ snd ACK +---------+delete TCB +---------+
------------------------>|TIME WAIT|------------------>| CLOSED |
+---------+ +---------+
Run Code Online (Sandbox Code Playgroud)
#!/usr/bin/env python
from socket import socket, AF_PACKET, SOCK_RAW
s = socket(AF_PACKET, SOCK_RAW)
#s.bind(("eth1", 0))
# We're putting together an ethernet frame here,
# NOTE: Not a full TCP frame, this is important to remember!
src_addr = "\x01\x02\x03\x04\x05\x06"
dst_addr = "\x01\x02\x03\x04\x05\x06"
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x1a\x2b\x3c\x4d"
ethertype = "\x08\x01"
s.send(dst_addr+src_addr+ethertype+payload+checksum)
Run Code Online (Sandbox Code Playgroud)
发现一些我几乎没有开始使用的旧代码,可能会派上用场:https : //github.com/Torxed/Scripts/tree/master/python/Laboratory
| 归档时间: |
|
| 查看次数: |
5772 次 |
| 最近记录: |