1
Cyshall 2019-08-31 16:43:52 +08:00 via iPhone
recvfrom()这个 syscall 最后两个参数就是发送方的地址信息阿。
|
2
skinny OP @Cyshall 那个是成功的时候才有啊。比如 server_sock.recvfrom(64),client 发送的数据报大小小于或等于 64,一切正常,返回(data, address),可如果对方发送了 65 个字节,server_sock.recvfrom(64)就会抛 OSError,也就获取不到了,OSError 实例里也没有这个信息。
|
3
skinny OP 如果非要 hack 底层或写一大坨 ctypes 代码才能获取,那我就放弃算了……
|
4
skinny OP 看了下 CPython socket 模块的 C 代码,没希望了……要么换语言,要么改一坨代码。
|
5
lcdtyph 2019-08-31 18:01:47 +08:00 via iPhone
试一下 MSG_TRUNC 这个 flag ?
|
6
fengtons 2019-08-31 18:02:13 +08:00 via Android
试一下 recvmsg 看行不行
|
7
elfive 2019-08-31 18:15:44 +08:00 via iPhone
一般 UDP 包大小以不超过 MTU 为最佳,所以我一般缓冲区会根据网络类型设定不同的缓冲区大小
|
8
BingoXuan 2019-08-31 19:02:24 +08:00 via Android
udp 是一个一个的消息,一般都会 recv 大小是 mtu 值。如果是 tcp 流,你可以源源不断地 recv。
|
9
skinny OP |
10
aguesuka 2019-09-01 00:47:39 +08:00 via Android
用 noi,超过 buff 的数据会被丢弃
|
11
aguesuka 2019-09-01 00:49:13 +08:00 via Android
没看到是 python
|
12
elfive 2019-09-01 06:40:44 +08:00 via iPhone
@skinny #9 Python 抛异常其实也算能理解,毕竟 udp socket 在调用 recvfrom()以后会清空内核中对应 udp 端口的接收缓冲区,Python 可能认为收到不完整的内容就是一种异常,所以需要你特别注意,你就封装一下,用 try...catch 捕获处理这个异常就好了。这一点,所有 udp socket 其实都一样。只是有些库或语言帮你处理了,有些则没有而已。
|
13
skinny OP @elfive 严肃的说,对于 UDP Server,最好还是是使用一个 64K 的大接收缓冲区,反正无论对面怎么样都发不了大于这个的数据报,接收后交给 Handler 检查处理以及记录,所以主楼的问题就是我有点钻牛角尖了,只是不爽 Python 就只是抛异常,却不告诉我异常是哪个源地址造成的。
|
14
elfive 2019-09-01 08:31:25 +08:00 via iPhone
@skinny #13 直接分配 64K,确实是最稳妥暴力的解决方法。但如果真的有这种大小的数据过来,正常的用户通讯肯定会受到不小影响。有点类似 DDOS 的感觉了
|
15
skinny OP @elfive 正儿八经的 UDP Server 应用肯定不能拿 Python 这样写了,我是写一个 Python 网络服务测试工具时需要一个加密代理(你懂的……),却没有找到合适趁手简单好用的库,所以临时自己写一个简单一点的。
|
16
dazhangpan 2019-09-01 15:10:42 +08:00
目测用 kprobe + ftrace 可行
在内核收取的方法里看 |