socket()模块函数
要使用socket.socket()函数来创建套接字。其语法如下:
socket(socket_family, socket_type, protocol=0)
socket_family 可以是AF_UNIX 或AF_INET。socket_type 可以是SOCK_STREAM 或SOCK_DGRAM。
这几个常量的意义可以参考之前的解释。protocol 一般不填,默认值为0。
创建一个TCP/IP 的套接字,你要这样调用socket.socket():
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
同样地,创建一个UDP/IP 的套接字,你要这样:
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
由于socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。使用
'from socket import *',我们就把socket 模块里的所有属性都带到我们的命名空间里了,这样能
大幅减短我们的代码。
tcpSock = socket(AF_INET, SOCK_STREAM)
当我们创建了套接字对象后,所有的交互都将通过对该套接字对象的方法调用进行。
套接字对象(内建)方法
表16.1 中,我们列出了最常用的套接字对象的方法。在下一个小节中,我们将分别创建TCP 和
UDP 的客户和服务器,它们都要用到这些方法。虽然我们只关心Internet 套接字,但是这些方法在
Unix 套接字中的也有类似的意义。
表16.1 套接字对象的常用函数
函数 描述
服务器端套接字函数
s.bind() 绑定地址(主机,端口号对)到套接字
s.listen() 开始TCP 监听
s.accept() 被动接受TCP 客户的连接,(阻塞式)等待连接的到来
客户端套接字函数
s.connect() 主动初始化TCP 服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛异常
公共用途的套接字函数
s.recv() 接收TCP 数据
s.send() 发送TCP 数据
s.sendall() 完整发送TCP 数据
s.recvfrom() 接收UDP 数据
s.sendto() 发送UDP 数据
s.getpeername() 连接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字
Blocking-Oriented Socket Methods
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout()a 设置阻塞套接字操作的超时时间
s.gettimeout()a 得到阻塞套接字操作的超时时间
面向文件的套接字的函数
s.fileno() 套接字的文件描述符
s.makefile() 创建一个与该套接字关连的文件
a. Python 2.3 版本新加入的函数
创建一个TCP 服务器
我们首先将给出一个关于如何创建一个通用的TCP 服务器的伪代码,然后解释我们都做了些
什么。要注意的是,这只是设计服务器的一种方法,当你对服务器的设计有了一定的了解之
后,你就能用你所希望的方式来修改这段伪代码:
ss = socket() # 创建服务器套接字
ss.bind() # 把地址绑定到套接字上
ss.listen() # 监听连接
inf_loop: # 服务器无限循环
cs = ss.accept() # 接受客户的连接
comm_loop: # 通讯循环
cs.recv()/cs.send() # 对话(接收与发送)
cs.close() # 关闭客户套接字
ss.close() # 关闭服务器套接字(可选)
所有的套接字都用socket.socket()函数来创建。服务器需要“坐在某个端口上”等待请求。所
以它们必需要“绑定”到一个本地的地址上。由于TCP 是一个面向连接的通讯系统,在TCP 服务器
可以开始工作之前,要先完成一些设置。TCP 服务器必需要“监听”(进来的)连接,设置完成之后,
服务器就可以进入无限循环了。
一个简单的(单线程的)服务器会调用accept()函数等待连接的到来。默认情况下,accept()
函数是阻塞式的,即程序在连接到来之前会处于挂起状态。套接字也支持非阻塞模式。请参阅相关
文档或操作系统手册以了解为何及如何使用非阻塞套接字。
一旦接收到一个连接,accept()函数就会返回一个单独的客户的套接字用于后续的通讯。使用
新的客户套接字就像把客户的电话转给一个客户服务人员。当一个客户打电话进来的时候,总机接
了电话,然后把电话转到合适的人那里来处理客户的需求。
这样就可以空出总机,也就是最初的那个服务器套接字,于是,话务员就可以等待下一个电话
(客户的请求),与此同时,前一个客户与对应的客户服务人员在另一条线路上进行着他们自己的对
话。同样的,当一个请求到来时,要创建一个新的端口,然后直接在那个端口上与客户对话,这样
就可以空出主端口来接受其它客户的连接。
在临时套接字创建好之后,通讯就可以开始了。客户与服务器都使用这个新创建的套接字进行
数据的发送与接收,直到通讯的某一方关闭了连接或发送了一个空字符串之后,通讯就结束了。
在代码中,当客户连接关闭后,服务器继续等待下一个客户的连接。代码的最后一行,会把服
务器的套接字关闭。由于服务器处在无限循环中,不可能会走到这一步,所以,这一步是可选的。
我们写这一句话的主要目的是要提醒读者,在设计一个更智能的退出方案的时候,比方说,服务器
被通知要关闭的时,要确保close()函数会被调用。
在例16.1 tsTserv.py 文件中,会创建一个TCP 服务器程序,这个程序会把客户发送过来的字
符串加上一个时间戳(格式:'[时间]数据')返回给客户。
阅读(966) | 评论(0) | 转发(0) |