如何解决无法从套接字连接获取完整数据
我正在尝试编写一个从服务器接收数据流的套接字客户端。 我能够获得前几个字节,但随后就中断了。
代码:
import socket
import sys
readOut = 0 # serial data
ipaddr = "192.168.1.246" # ip address of digital thermometer socket server
#def hitsocket(ipaddr):
#with socket.socket(socket.AF_INET,socket.soCK_STREAM) as s:
print ("Starting up")
connected = False
with socket.socket(socket.AF_INET,socket.soCK_STREAM) as s:
try:
s.connect((ipaddr,8080))
amount_received = 0
while True:
data = s.recv(1024)
amount_received += len(data)
if not data:
break
print(amount_received,end="\n")
while True:
print ("Reading: ",amount_received)
if "Fahrenheit" in amount_received:
cread = amount_received[22:-2]
newcread = float(cread)
print("readOut ",amount_received,"cread ",cread,"newcread ",newcread)
break
print ("Restart")
finally:
print(sys.stderr,'closing socket')
s.close()
输出:
Starting up
19
Writing: 1
Reading: 19
<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> closing socket
Traceback (most recent call last):
File "climatemnGrdebug-v3.py",line 58,in <module>
if "Fahrenheit" in amount_received:
TypeError: argument of type 'int' is not iterable
kermit@whale:~/dev $ netcat 192.168.1.246 8080
mcp9809 Fahrenheit 72.0500
mcp9809 Fahrenheit 72.0500
mcp9809 Fahrenheit 72.0500
mcp9809 Fahrenheit 72.1625
mcp9809 Fahrenheit 72.0500
mcp9809 Fahrenheit 72.0500
mcp9809 Fahrenheit 72.1625
mcp9809 Fahrenheit 72.0500
我已经阅读了 python 文档,也查看了其他示例,但我还是弄错了。
解决方法
您在 amount_received
中查找单词“Fahrenheit”,它是数据的整数计数,而不是数据本身。接收到的数据在 data
中,它是一个 Bytes
字符串。 recv
不知道服务器发送的行,它只是抓取一些字节。但是您可以缓冲接收数据并自己找到换行符。假设数据是字节编码的(ascii,Windows 代码页,utf-8 - 但不是 utf-16),你可以搜索 b'\n'
的字节,一旦你知道你有一行,将其转换为字符串进一步处理。在此示例中,我编写了一个类,该类读取字节流并在找到时返回行。
客户端.py
import socket
import sys
readOut = 0 # serial data
#ipaddr = "192.168.1.246" # ip address of digital thermometer socket server
# todo: change as needed for test server or real server
ipaddr = 'localhost'
ipport = 8080
#def hitsocket(ipaddr):
#with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
print ("Starting up")
connected = False
class LineReader:
def __init__(self,socket,encoding='ascii'):
self.s = socket
self.encoding = encoding
self.buf = b''
self.closed = False
def readline(self):
while True:
index = self.buf.find(b'\n')
if index >= 0:
line = self.buf[:index+1]
self.buf = self.buf[index+1:]
return line.decode(self.encoding)
if self.closed:
line = self.buf
self.buf = b''
return line.decode(self.encoding)
data = self.s.recv(1024)
self.closed = len(data) == 0
print("raw recv:",data)
self.buf += data
with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
try:
s.connect((ipaddr,ipport))
reader = LineReader(s)
while True:
line = reader.readline()
if not line:
break
print(f"Reading: {line}",end='')
if "Fahrenheit" in line:
cread = line[22:-2]
newcread = float(cread)
print("cread ",cread,"newcread ",newcread)
finally:
print('closing socket',file=sys.stderr)
s.close()
testserver.py
import socket
import time
test_data = b'mcp9809 Fahrenheit 72.0500\n'
s = socket.socket()
# todo: change as needed,but must match address in client script
s.bind(('localhost',8080))
s.listen()
while True:
c,addr = s.accept()
# send in framents to test reassembler
c.send(test_data)
time.sleep(.1)
c.send(test_data * 2)
time.sleep(.1)
c.send(test_data[:9])
time.sleep(.1)
c.send(test_data[9:])
c.send(test_data * 3 + test_data[:9])
time.sleep(.1)
c.send(test_data[9:])
c.shutdown(socket.SHUT_RDWR)
c.close()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。