设为首页 收藏本站
查看: 238|回复: 0

[经验分享] Python的网络编程(五)

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-4-30 11:50:29 | 显示全部楼层 |阅读模式
socket的阻塞或同步编程
  


一、使用socket

网络编程中最基本的部分就是socket(套接字)。socket有两种:服务端socket和客户端 socket。在你创建了一个服务端socket之后,你告诉它去等待连接。然后它将监听某个网络地址(形如:xxx.xxx.xxx.xxx:xxx) 直到客户端连接。然后这两端就可以通信了。

处理客户端socket通常比处理服务端socket要容易一点,因为服务端必须时刻准备处理来自客户端的连接,并且它必须处理多个连接,而客户端只需要简单的连接,然后做点什么,然后断开连接。

实例化一个socket时,可以指定三个参数:地址系列(默认为socket.AF_INET)、流socket(这是个默认值: socket.SOCK_STREAM)或数据报socket(socket.SOCK_DGRAM)、协议(默认值是0)。对于简单的socket,你可以不指定任何参数而全部使用默认值。

服务端socket在使用bind方法之后调用listen方法去监听一个给定的地址。然后,客户端socket就可以通过使用connect方法(connect方法所使用的地址参数与bind相同)去连接服务端。listen方法要求一个参数,这个参数就是等待连接队列中所能包含的连接数。

一旦服务端socket调用了listen方法,就进入了临听状态,然后通常使用一个无限的循环:1、开始接受客房端的连接,这通过调用accept方法来实现。调用了这个方法后将处于阻塞状态(等待客户端发起连接)直到一个客户端连接,连接后,accept返回形如(client,address)的一个元组,其中client是一个用于与客户端通信的socket,address是客户端的形如xxx.xxx.xxx.xxx:xxx的地址;2、然后服务端处理客户端的请求;3、处理完成之后又调用1。

关于传输数据,socket有两个方法:send和recv。send使用字符串参数发送数据;recv参数是字节数,表示一次接受的数据量,如果你不确定一次该接受的数据量的话,最好使用1024。

下面给出一个最小的服务器/客户机的例子:

服务端:

import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
while True:
    c, addr = s.accept()
    print 'Got connection from', addr
    c.send('Thank you for connecting')
    c.close()


客户端:

import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect((host, port))
print s.recv(1024)


注意:如果你使用Ctrl-C来停止服务端的话,如果再次使用相同的端口可能需要等待一会儿。

二、使用SocketServer

SocketServer模块简单化了编写网络服务器的工作。
它提供了四个基本的服务类:TCPServer(使用TCP协议)、UDPServer(使用数据报)、UnixStreamServer、

UnixDatagramServer。UnixStreamServer和UnixDatagramServer用于类Unix平台。
这四个类处理请求都使用同步的方法,也就是说,在下一个请求处理开始之前当前的请求处理必须已完成

。 

用SocketServer创建一个服务器需要四步:

1、通过子类化BaseRequestHandler类和覆盖它的handle()方法来创建一个请求处理器类,用于处理进来

的请求;
2、实例化服务类如TCPServer,并传递给它参数:服务器地址和请求处理器类;
3、调用服务实例对象的handle_request()或serve_forever()方法去处理请求。

下面使用SocketServer用同步的方法写一个最简单的服务器:

from SocketServer import TCPServer, StreamRequestHandler
#第一步。其中StreamRequestHandler类是BaseRequestHandler类的子类,它为流socket定义了
#rfile和wfile方法
class Handler(StreamRequestHandler):
    def handle(self):
        addr = self.request.getpeername()
        print 'Got connection from', addr
        self.wfile.write('Thank you for connecting')

#第二步。其中''代表运行服务器的主机
server = TCPServer(('', 1234), Handler)
#第三步。serve_forever()导致进入循环状态
server.serve_forever()


注意:使用阻塞或同步的方法一次只能连接一个客户端,处理完成后才能连接下一个客户端。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-371169-1-1.html 上篇帖子: Python的网络编程(三) 下篇帖子: Python转义字符列表[转]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表