Python socket.sendall 发送看似任意长度的数据
我正在用Python 3的socket库写一个小脚本,目的是把通话记录发送到服务器。
每条记录的大小正好是109个字节。
当我在发送数据的过程中观察接收端和使用Wireshark工具时,我发现有些数据包的大小明显不对。Wireshark显示,有一个数据包虽然数据是正确的,但它的大小却是170个字节。还有一些数据包的大小超过了1500个字节。
有时候,接收端会拒绝两个数据包,大小分别是59和50个字节(加起来正好是一个完整的数据包的大小)。
有没有办法让这个过程更加可靠呢?
这是我正在使用的方法。
def connect_to_collector(iterator_obj, host, port, rate, count):
if count == None:
count = len(iterator_obj.mylist)
delay = 3600 / int(rate)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, int(port)))
print ('\n[+] Connected to {} on port {}'.format(host, port))
start = timer()
i = 0
for record in iterator_obj:
if i < count:
try:
if len(record) is not length:
print ('the length was ', length)
s.sendall(record)
time.sleep(delay)
i += 1
except:
e = sys.exc_info()
print ('SEND ERROR OCCURRED ', e)
print ('\n[+] Sent {} to {} on port {} in {:.4f} seconds'.format(i, host, port, timer() - start))
sys.exit()
if verbose:
print ('Sending : |{:' '<150}| record number |{}|'.format(record, i))
if i >= count:
break
# Clean up
print ('\n[+] Sent {} to {} on port {} in {:.4f} seconds'.format(count, host, port, timer() - start))
s.close()
补充说明:在
for record in iterator_obj:
if i < count:
try:
if len(record) is not length:
print ('the length was ', length)
s.sendall(record)
迭代器内部的while循环有一个bug,导致sendall()函数有时会被多次调用来发送同一条记录。
我已经把那个循环去掉了。
1 个回答
0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
有没有办法让这个工作得更可靠一些?
你这里使用的是TCP协议,而TCP是一种流协议,不是数据报(包)协议。这意味着整个连接被视为一个连续的数据流,TCP会根据需要进行优化,比如把一些数据一起发送,或者把其他数据拆开发送。如果你期待每次接收的数据正好对应一次发送,那你就理解错了。
如果你想要使用数据报协议,可以选择UDP。不过这样的话,你就得自己处理丢失的数据包、数据包的顺序问题或者重复数据包的问题。有一些协议,比如SCTP,像UDP一样是数据报协议,但又具备TCP的可靠性。不过这些协议可能不是在所有地方都能使用,使用时可能会遇到防火墙的问题。