use*_*953 0 python sockets tcp
以下代码适用于可以接收字符串的python服务器.
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 8001
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connection address:', addr
while 1:
length = conn.recv(1027)
data = conn.recv(int(length))
import StringIO
buff = StringIO.StringIO()
buff.write(data)
if not data: break
print "received data:", data
conn.send('Thanks') # echo
get_result(buff)
conn.close()
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我编辑此代码或创建一个类似的代码,以便能够接收图像而不是字符串?
首先,您的代码实际上无法接收字符串.套接字是字节流,而不是消息流.
这一行:
length = conn.recv(1027)
Run Code Online (Sandbox Code Playgroud)
...将接收1到1027字节的任何地方.
你需要循环每个recv并积累一个缓冲区,如下所示:
def recvall(conn, length):
buf = b''
while len(buf) < length:
data = conn.recv(length - len(buf))
if not data:
return data
buf += data
return buf
Run Code Online (Sandbox Code Playgroud)
现在你可以让它像这样工作:
while True:
length = recvall(conn, 1027)
if not length: break
data = recvall(conn, int(length))
if not data: break
print "received data:", data
conn.send('Thanks') # echo
Run Code Online (Sandbox Code Playgroud)
StringIO出于性能原因,您可以使用或使用其他技术而不是串联,但我将其排除在外,因为它更简单,更简洁,并且理解代码比性能更重要.
同时,值得指出的是1027字节是用于长度前缀的荒谬的大量空间.此外,您的发送代码必须确保实际发送1027字节,无论如何.并且您的响应必须始终长度为6个字节才能实现.
def send_string(conn, msg):
conn.sendall(str(len(msg)).ljust(1027))
conn.sendall(msg)
response = recvall(conn, 6)
return response
Run Code Online (Sandbox Code Playgroud)
但至少现在它是可行的.
那么,为什么你认为它有效?
TCP是字节流,而不是消息流.无法保证send一方的单一与另一方的下一方匹配recv.但是,如果您在同一台计算机上运行双方,发送相对较小的缓冲区,并且没有严重加载计算机,则它们通常会碰巧匹配1对1.毕竟,每次调用时recv,另一方可能只有send一个消息的时间,它本身就位于操作系统的缓冲区中,因此操作系统只是为您提供了全部内容.因此,您的代码似乎可以在初始测试中使用.
但是,如果您通过路由器将消息发送到另一台计算机,或者您等待足够长时间让另一方send拨打多个电话,或者您的消息太大而无法放入单个缓冲区,或者您只是运气不好,那么可能是在缓冲区中等待的2-1/2条消息,操作系统将为您提供整条2-1/2条消息.然后你的下一个recv将获得剩余的1/2消息.
那么,你如何使图像工作?那么,这取决于你的意思.
您可以将图像文件作为字节序列读入内存,并调用send_string该序列,它将正常工作.然后另一方可以保存该文件,或将其解释为图像文件并显示它或任何它想要的.
或者,您可以使用类似的方法PIL将图像文件解析并解压缩为位图.然后,您以某种方式(例如,pickle它),send_string标题,然后send_string位图编码标题数据(宽度,高度,像素格式等).
如果标题具有固定大小(例如,它是一个可以序列化的简单结构struct.pack),并且包含足够的信息以便另一方以字节为单位计算出位图的长度,则不需要send_string每个标题; 只是使用conn.sendall(serialized_header)那么conn.sendall(bitmap).
| 归档时间: |
|
| 查看次数: |
2270 次 |
| 最近记录: |