我正在使用python套接字一段时间,我写了一些很好的简单程序。
我每次都面临的问题是关于在套接字中发送和接收方法! 给你一个基本而简单的例子:
这是接收者(服务器!):
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 4001)) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.listen(5) while True: conn, addr = s.accept() print conn, addr data1 = conn.recv(64) data2 = conn.recv(64) print 'uname is %s , password is: %s' %(data1, data2, ) conn.close()
这是发件人(或客户端!):
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('', 4001)) uname = raw_input('enter username>') passw = raw_input('enter password>') s.send(uname) s.send(passw) print 'exiting ...' s.close()
所以问题是,为什么服务器在第一个s.recv()方法中同时接收uname和passw?这意味着data2始终为空!
我真的不知道当客户端使用s.send()时会发生什么。我在想每个s.send()都会向目的地发送一个“数据包”(ip,port)!!
有人可以向我解释为什么第二个代码(另一个客户端)正在工作吗?
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('', 4001)) uname = raw_input('enter username>') s.send(uname) passw = raw_input('enter password>') s.send(passw) print 'exiting ...' s.close()
答案 0 :(得分:3)
我也面临类似的问题。然后我实现了一个协议,一次发送和接收一条消息。希望这个链接能够提供很多帮助:LINK
答案 1 :(得分:2)
socket.SOCK_STREAM
表示您正在通过TCP进行通信。这意味着,如果您调用send
,您的数据将被推送到系统的网络堆栈。两个send
调用都会一个接一个地调用。
如果使用TCP,系统会决定数据包大小。因此,uname
和passw
可能会在一个数据包中发送,甚至可能以任何其他方式进行拆分。
在接收方,data1
最多可接收64个字节,这对uname
和passw
来说已足够。
上面的解释也说明了为什么第二个有效:
您需要一段时间来发送uname
和passw
。在此期间,您的操作系统决定发送数据包(即刷新网络缓冲区)。
当您使用流时,您不应该考虑数据包而是考虑流。 send
调用仅意味着:在我的网络堆栈上推送一些数据(如管道)。
如果您对包裹感兴趣, 您可能会尝试使用UDP进行试验:
socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
使用这种套接字,您的第一个发件人将按预期工作