python网络编程学习笔记(一)


Posted in Python onJune 09, 2014

学习用书:《python 网络编程基础》作者John Goerzen

第一部分底层网络学习

        Python提供了访问底层操作系统Socket接口的全部方法,需要的时候这些接口可以提供灵活而强有力的功能。

(1)基本客户端操作

        在《python 网络编程基础》一书中,作者列出了一个简单的Python客户端程序,具体如下:

import socket,sys
port =70
host=sys.argv[1]
filename=sys.argv[2]
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
s.sendall(filename+"\r\n")
while 1:
    buf=s.recv(2048)
    if not len(buf):
        break
    sys.stdout.write(buf)

该程序实现的是Gopher协议,实现从主机上请求相关文档的功能。(Gopher是Internet上一个非常有名的信息查找系统,它将Internet上的文件组织成某种索引,很方便地将用户从Internet的一处带到另一处。在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本很少被使用。)
       于是,我按照书上的语句进行了一下测试,在dos下运行python gopherclient.py quux.org。但是系统提示为

Traceback (most recent call last):
File "gopherclient.py", line 5, i
filename=sys.argv[2]
IndexError: list index out of range

看了一下,sys.argv只有两个元素['gopherclient.py', 'quux.org/']所以filename=sys.argv[2]就超出下界了。可是为什么会出现这个原因呢?是书里面写错了吗,因为我也是初学socket,不是很了解,所以我也是没有找到原因,如果哪位大牛知道是什么原因,希望能给讲解一下。

(2)基本服务器操作
        《python 网络编程基础》一书中同样给出了一个简单的服务器程序,具体如下:

import socket
host=''
port=51423
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(1)
print "Server is running on port %d;press Ctrl-C to terminate." %port
while 1:
    clientsock,clientaddr=s.accept()
    clientfile=clientsock.makefile('rw',0)
    clientfile.write("welcome,"+str(clientaddr)+'\n')
    clientfile.write("Please enter a string:")
    line=clientfile.readline().strip()
    clientfile.write("You entered %d characters.\n" %len(line))
    clientfile.close()
    clientsock.close()

该程序运行后,提示“Server is running on port 51423:press Ctrl-C to terminate”。此时,通过另一台机器telnet本机器的51423端口,如telnet 127.0.0.1:51423,此时会提示welcome 127.0.0.1 ****,please enter a string:。 然后输入几个字符后,会返回你输入字符的个数。

这里就该程序进行一下分析:

1、首先导入socket模块,给host和port赋值。
2、调用socket.socket()来建立一个socket赋值给s。socket.socket(domain, type, protocol).domain参数的值有AF_UNIX,AF_LOCAL,AF_INET,PF_UNIX,PF_LOCAL,PF_INET。这几个值中AF_UNIX=AF_LOCAL, PF_UNIX=PF_LOCAL, AF_LOCAL=PF_LOCAL, AF_INET=PF_INET。一般来说,AF 表示ADDRESS FAMILY 地址族,PF 表示PROTOCOL FAMILY 协议族,但这两个宏定义是一样的,所以使用哪个都没有关系。参数type指定socket的类型:SOCK_STREAM提供有序、可靠、双向及基于连接的字节流。SOCK_DGRAM支持数据报。SOCK_SEQPACKET提供有序、可靠、双向及基于连接的数据报通信。SOCK_RAW提供对原始网络协议的访问。SOCK_RDM提供可靠的数据报层,但是不保证有序性。protocol一般取0(为什么取0我也没搞清楚,放在以后明白了再写上吧)。
3、s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)。setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项,但本函数仅定义了最高的“套接口”层次上的选项。选项影响套接口的操作,诸如加急数据是否在普通数据流中接收,广播数据是否可以从套接口发送等等。 这个函数中,第一个参数为协议层参数,指明了希望访问一个选项所在的协议栈。通常我们需要使用下面中的一个:
SOL_SOCKET来访问套接口层选项
SOL_TCP来访问TCP层选项
第二个参数是与第一个参数相对应的。第一个参数决定了协议层level,第二个参数决定了该协议层下选项组合。SOL_SOCKET的选项组合如下:
协议层 选项名字
SOL_SOCKET SO_REUSEADDR
SOL_SOCKET SO_KKEPALIVE
SOL_SOCKET SO_LINGER
SOL_SOCKET SO_BROADCAST
SOL_SOCKET SO_OOBINLINE
SOL_SOCKET SO_SNDBUF
SOL_SOCKET SO_RCVBUF
SOL_SOCKET SO_TYPE
SOL_SOCKET SO_ERROR
具体的一些组合用法可见:http://wenku.baidu.com/view/23013b7101f69e3143329402.html
第三个参数设为1,这里我也没很明白其中的意思,我试着把1换成50,结果是一样的。换成0也是可以的,没发现什么区别。希望大牛们给指点一下。
4、s.bind((host,port))绑定主机端口。
5、s.listen(1):listen函数使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。这里的参数涉及到一些网络的细节。在进程正理一个一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态,有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。如果这个情况出现了,服务器进程希望内核如何处理呢?内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接,这样的一个队列内核不可能让其任意大,所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。毫无疑问,服务器进程不能随便指定一个数值,内核有一个许可的范围。这个范围是实现相关的。很难有某种统一,一般这个值会小30以内。这里设定为1表示每次最多只有一个等候处理的连接。
6、while循环从accept()函数开始。程序会在连接了一个客户端后关闭socket。当某个客户端连接的时,accept返回两个信息,一个新的连接客户端socket和客户端的ip地址、端口号。如在上面的例子中添加print语句输出clientsock和clientaddr,你会发现clientsock为socket.socketobject,clientaddr=('客户端Ip',端口)。后面的循环中使用了文件类对象,服务器接着显示出一些介绍性信息,从客户端读一个字符串,显示一个应答,最后关闭客户端socket。

Python 相关文章推荐
python通过colorama模块在控制台输出彩色文字的方法
Mar 19 Python
python正则表达式之作业计算器
Mar 18 Python
python使用标准库根据进程名如何获取进程的pid详解
Oct 31 Python
python 中的列表生成式、生成器表达式、模块导入
Jun 19 Python
python excel转换csv代码实例
Aug 26 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
Oct 14 Python
浅析Python+OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估
Oct 17 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
Mar 05 Python
django 实现手动存储文件到model的FileField
Mar 30 Python
Kmeans均值聚类算法原理以及Python如何实现
Sep 26 Python
python 日志模块logging的使用场景及示例
Jan 04 Python
python3 kubernetes api的使用示例
Jan 12 Python
有关wxpython pyqt内存占用问题分析
Jun 09 #Python
wxpython 最小化到托盘与欢迎图片的实现方法
Jun 09 #Python
Python实例之wxpython中Frame使用方法
Jun 09 #Python
wxpython学习笔记(推荐查看)
Jun 09 #Python
wxPython中文教程入门实例
Jun 09 #Python
python操作xml文件详细介绍
Jun 09 #Python
实例讲解python函数式编程
Jun 09 #Python
You might like
php反弹shell实现代码
2009/04/22 PHP
PHP substr 截取字符串出现乱码问题解决方法[utf8与gb2312]
2011/12/16 PHP
C#静态方法与非静态方法实例分析
2014/09/22 PHP
7个鲜为人知却非常实用的PHP函数
2015/07/01 PHP
在PHP中使用FastCGI解析漏洞及修复方案
2015/11/10 PHP
PHP通过curl获取接口URL的数据方法
2018/05/31 PHP
PHP实现字符串的全排列详解
2019/04/24 PHP
给网站上的广告“加速”显示的方法
2007/04/08 Javascript
基于jquery用于查询操作的实现代码
2010/05/10 Javascript
Extjs显示从数据库取出时间转换JSON后的出现问题
2012/11/20 Javascript
原生javaScript实现图片延时加载的方法
2014/12/22 Javascript
JavaScript开发Chrome浏览器扩展程序UI的教程
2016/05/16 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
2016/05/24 Javascript
Node.js 实现简单的接口服务器的实例代码
2017/05/23 Javascript
详解Vue.js自定义tipOnce指令用法实例
2018/12/19 Javascript
详解小程序如何动态绑定点击的执行方法
2019/11/26 Javascript
python使用百度翻译进行中翻英示例
2014/04/14 Python
在Python的struct模块中进行数据格式转换的方法
2015/06/17 Python
Python实现一个转存纯真IP数据库的脚本分享
2017/05/21 Python
python 读取视频,处理后,实时计算帧数fps的方法
2018/07/10 Python
Python3爬虫学习之爬虫利器Beautiful Soup用法分析
2018/12/12 Python
python中with语句结合上下文管理器操作详解
2019/12/19 Python
python扫描线填充算法详解
2020/02/19 Python
详解Pycharm出现out of memory的终极解决方法
2020/03/03 Python
地球鞋加拿大官网:Earth Shoes Canada
2020/11/17 全球购物
SQL注入攻击的种类有哪些
2013/12/30 面试题
为什么说Ruby是一种真正的面向对象程序设计语言
2012/10/30 面试题
自荐信格式范文
2013/10/07 职场文书
课程设计心得体会
2013/12/28 职场文书
仓库管理员岗位职责
2014/03/19 职场文书
学校清明节活动总结
2014/07/04 职场文书
会计专业自荐书
2014/07/08 职场文书
公司周年庆典标语
2014/10/07 职场文书
公积金具结保证书
2015/05/11 职场文书
小程序实现悬浮按钮的全过程记录
2021/10/16 HTML / CSS
实战 快速定位MySQL的慢SQL
2022/03/22 MySQL