如何在Python中使用套接字建立双向通信?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Python中使用套接字建立双向通信?相关的知识,希望对你有一定的参考价值。
所以,我有一个服务器脚本从客户端脚本接收图像,并且应该发送一个确认“OK”。但承认永远不会通过。
服务器脚本 -
import socket,sys
s = socket.socket()
print("Socket successfully created")
port =80
s.bind(('', port))
print("socket binded to %s" %(port))
s.listen(5)
print("socket is listening")
while True:
c, addr = s.accept()
print('Got connection from', addr)
file_name=s.recv(1024)
file_name=fil_ename.decode("utf-8")
with open(file_name,"wb")as f:
while True:
data=c.recv(1024)
if not data:
break
f.write(data)
c.send(bytes('Thank you ! File received.',"utf-8"))
c.close()
客户端脚本 -
import socket
s = socket.socket()
# Define the port on which you want to connect
port = 80
s.connect(('IP address of my server', port))
s.send(bytes("hand.jpeg","utf-8"))
f=open("back.jpeg","rb")
data=f.read(512)
while data:
s.send(data)
data=f.read(512)
f.close()
print(s.recv(10))
服务器不发送任何确认,似乎卡在for循环中。但是,如果我从服务器脚本中删除行c.send(bytes('Thank you ! File received.',"utf-8"))
,代码运行良好。此外,如果我从服务器端删除接收部分并只发送确认部分,即c.send(bytes('Thank you ! File received.',"utf-8"))
,客户端将收到该消息。但如果在服务器端进行了receive(图像文件)和确认的组合,如代码所示,则服务器端无法响应。
需要注意的重要一点是,在KeyBoardInterrupting上面的程序中,它显示服务器端脚本被挂起/卡在data=c.recv(1024)
行中。但是如果删除确认行,同样的问题就会消失。
注意: - 客户端脚本在我的本地计算机上运行,服务器端脚本在Google云虚拟机实例上运行。
请帮忙。谢谢。
嗯......我不认为我完全相信你对这种行为的描述。但我确实知道什么是错的。您的服务器位于接收循环中是完全合理的,因为客户端没有向连接发出EOF信号。在什么情况下你认为这实际上是break
?
if not data:
break
答案是客户端需要close
套接字,或使用shutdown(SHUT_WR)
表示它不会再发送任何数据。所以,在客户端做你想做的事:
...
f.close()
s.shutdown(socket.SHUT_WR)
...
现在,下次服务器调用recv
时,它将返回一个空字符串,并且将获取上面的break
。
这使得连接在一个方向上打开而在另一个方向上打开。因此客户端将无法再发送任何数据。但是,服务器仍然能够发送到客户端,直到它关闭套接字(或使用shutdown
本身)。
还有一个更微妙的问题。您假设您的第一个服务器端recv
将仅接收包含您的文件名的字节。 99.9%的时间可行。但是当服务器第一次调用send
时,下一个客户端recv
的数据也可能可用。这可能会给你一个虚假的文件名(虽然不一定是非法的)并且肯定意味着你的文件没有忠实地转移。
你永远不应该假设一个对等体提供的单个send
的数据将被另一方的相应单个recv
接收。收到的数据可能或多或少,由应用程序决定数据的框架,以确保它完全收到预期的数量。
这里
while True:
data=c.recv(1024)
if not data:
break
f.write(data)
它会在收到消息后循环回等待消息,因为您在接收数据后没有中断while循环。 if not data:
没有做任何事情,因为recv()
停止并等待它得到消息,因此data
永远不会是什么。您应该在收到消息后通过在break
之后添加f.write(data)
来中断循环,或者在循环中发送OK。
以上是关于如何在Python中使用套接字建立双向通信?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不同进程中建立Activity和Service之间的双向通信?