用户在使用 Python 进行网络通信时遇到了一个问题。在试图通过套接字接收数据时,即使数据已经发送,但程序却始终没有收到任何数据。代码如下:
from socket import *
http://www.jshk.com.cn/mb/reg.asp?kefu=xiaoding;//爬虫IP免费获取;
import array
import select
HOST = '169.254.0.10'
PORT = 10001
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
tcpCliSock.setblocking(0)
def dump(x):
dfile = open('dump','w')
dfile.write(x)
dfile.close
data='I'
tcpCliSock.send(data)
tcpCliSock.shutdown(1)
ready_to_read, ready_to_write, in_error = select.select(
[tcpCliSock],
[],
[],
30)
if ready_to_read == []:
print "sokadens"
data=''
while len(data)<10:
chunk = tcpCliSock.recv(1024)
print 'recv\'d %d bites'%len(data)
data=data+chunk
index=data.find('##IMJ')
if index == -1:
dump(data)
raise RuntimeError, "imahe get error"
datarr = array.array('B',data)
size=datarr[6]+datarr[7]<<8+datarr[8]<<16+datarr[9]<<24
ready_to_read, ready_to_write, in_error = select.select(
[tcpCliSock],
[],
[],
30)
if ready_to_read == []:
print "sokadens"
while len(data)<size:
chunk = tcpCliSock.recv(1024)
data=data+chunk
outfile=open('resim.jpg','w')
outfile.write(data[10:])
outfile.close
tcpCliSock.close()
在运行代码后,程序陷入 “recv’d 0 bites” 循环中。并且,当程序尝试从客户端获取数据时,它会抛出 “imahe get error” 异常。
2、解决方案
-
调整
recv()
方法的使用。
该代码中,问题所在是recv()
方法的使用不正确。
tcpCliSock.recv(1024)
这一行代码每次都会尝试接收 1024 字节的数据,而不考虑对方实际发送的数据量。 -
检查返回的字节数。
在recv()
方法的调用中,应该检查返回的字节数。 -
使用缓冲区保存数据
Python 中,可以利用recv()
方法保存接收的数据,进行相关计算后在进行下一次的接收。
import select
import socket
# 使用套接字的 `AF_INET` 和 `SOCK_STREAM` 创建 TCP 套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 将套接字设置为非阻塞
sock.setblocking(False)
# 服务器的地址和端口
# 根据实际服务器的信息进行修改
server_address = ('169.254.0.10', 10001)
# 连接服务器
sock.connect(server_address)
# 准备接收数据的缓冲区
buffer = ""
# 循环接收数据
while True:
# 检查套接字是否可读
ready_to_read, _, _ = select.select([sock], [], [], 30)
if ready_to_read:
# 从套接字接收数据
data = sock.recv(1024)
# 检查是否接收到数据
if not data:
# 服务器断开连接
break
# 将接收到的数据添加到缓冲区
buffer += data
# 处理缓冲区中的数据
# 在实际应用中,可以根据数据的格式和协议进行处理
# 如根据协议中的字段长度切割数据
# 关闭套接字
sock.close()
这种方法会一直等待数据,直到缓冲区中所有数据被处理完毕。如果数据量较大,可以考虑使用多线程或多进程来并行处理数据,以提高效率。