python icmp原始套接字实现

时间:2011-12-13 17:19:22

标签: python icmp raw-sockets

我对python比较陌生,所以请体谅......

我正在通过raw_sockets实现服务器和客户端。 我有必要的特权。

现在,服务器我定义了:

host = socket.gethostbyname(socket.gethostname())
address = (host, 22224)
sockSer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
sockSer.bind(address)
sockSer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
packet, addr = sockSer .recvfrom(4096)   # wait for packet from client

Q1)为什么我不能简单地输入:hosts ='localhost'。 如果我这样做,它不允许我写行:sockSer.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)。然后服务器没有收到我客户的消息。 只有在做gethostbyname(socket.gethostname())时我得到192.168.1.101 然后就可以了。

在另一个班级: 客户端套接字:

host = socket.gethostbyname(socket.gethostname())
address = (host, 22224)
sockCli = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)

Q2)我还需要输入:sockCli.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON) 或者sockCli.connect(地址)?似乎它没有connect命令。 对于客户端套接字?

现在,当我执行以下操作时会出现问题: 1)从客户端向服务器发送数据包:

header=...
payload='a'
sockCli.sendto(header + payload, address)

2)在服务器中接收数据包并将某些内容发送回客户端:

while(true):
    data, addr = sockSer.recvfrom(4096)
    header2=...
    payload2='b'
    sockSer.sendto(header2 + payload2, addr)

现在,我的重要问题是: Q3)服务器只向客户端发送了1个数据包,有效负载为“b”。 会发生什么,我的客户端实际上在while循环中收到2个数据包: 第一个数据包是客户端本身发送到服务器,另一个数据包是客户端从服务器获取的数据包。 因此我的输出是'ab'而不是简单的'b' 为什么会发生这种情况?

注意:我没有输入整个代码,但我认为我的语法,解析,标题组合等都是正确的。 我的代码中有明显的问题吗? 如果有必要,我会上传整个代码。

谢谢

2 个答案:

答案 0 :(得分:0)

我也得到了这个。 我的解决方案是在接收代码中添加一个判断,比如我发送Ping包所以我只想要ECHO回复(类型0代码0),我写

if type != 0:
     continue

你也可以写作     如果addr == my_ip:          继续

似乎没有任何顺利的解决方案

答案 1 :(得分:0)

Q1:我能够绑定到localhost并使用这两个参数调用IOCTL就好了。假设您的客户端也在同一系统上运行,请确保客户端发送到“localhost”,否则您的服务器将永远不会收到数据包。如果您的客户端在另一个系统上,显然您的服务器将永远不会收到数据包。

Q2:您不需要IOCTL来发送数据包。只需通过sendto()发送即可。

问题3:您看到两个回复的原因是,除了您自己的用户空间代码之外,内核还在处理回应请求。

虽然您可以使用ICMP进行任意消息传递,但正如其他人所指出的那样,这不是它的预期设计。您可能会发现您的数据部分在邮件回复中被截断。例如,在发送回应请求时,您的回复可能包含您发送的所有内容;但是,类型3代码3的回复可能不包括您的数据,而只包括ICMP标头的前8个字节。

相关问题