Python套接字中的发送和接收是如何工作的?
我在用Python做网络编程,已经写了一些简单的程序。
我遇到的问题和Python的socket发送和接收方法有关。给你一个基本的例子:
这是接收端(服务器):
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()时就收到了用户名和密码?这就意味着data2总是为空!
我不太明白当客户端执行s.send()方法时发生了什么。我原本以为每次s.send()实际上是把一个“数据包”发送到目标(IP,端口)!
有人能解释一下为什么第二段代码能正常工作吗?
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()
2 个回答
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)
使用这种类型的套接字,你的第一个发送者将会按预期工作。