0

我对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(address)?似乎它在没有连接命令的情况下工作。对于客户端套接字?

现在,当我执行以下操作时出现问题: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' 为什么会发生这种情况???

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

谢谢

4

2 回答 2

0

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

if type != 0:
     continue

你也可以写成好像 addr == my_ip: continue

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

于 2013-09-03T08:41:49.677 回答
0

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

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

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

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

于 2014-03-18T04:33:18.953 回答