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实现删除列表中满足一定条件的元素示例
Jun 12 Python
python3+mysql查询数据并通过邮件群发excel附件
Feb 24 Python
python如何通过twisted实现数据库异步插入
Mar 20 Python
python面向对象实现名片管理系统文件版
Apr 26 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
May 05 Python
TensorFlow梯度求解tf.gradients实例
Feb 04 Python
使用python绘制cdf的多种实现方法
Feb 25 Python
一些关于python 装饰器的个人理解
Aug 31 Python
Python实现EM算法实例代码
Oct 04 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
Jan 15 Python
python批量更改目录名/文件名的方法
Apr 18 Python
python 管理系统实现mysql交互的示例代码
Dec 06 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
2020显卡排行榜天梯图 显卡天梯图2020年3月最新版
2020/04/02 数码科技
用cookies来跟踪识别用户
2006/10/09 PHP
PHP学习资料汇总与网址
2007/03/16 PHP
php中对xml读取的相关函数的介绍一
2008/06/05 PHP
美图秀秀web开放平台--PHP流式上传和表单上传示例分享
2014/06/22 PHP
thinkPHP使用pclzip打包备份mysql数据库的方法
2016/04/30 PHP
PHP简单获取多个checkbox值的方法
2016/06/13 PHP
php 计算两个时间相差的天数、小时数、分钟数、秒数详解及实例代码
2016/11/09 PHP
php获取数据库结果集方法(推荐)
2017/06/01 PHP
Dom加载让图片加载完再执行的脚本代码
2008/05/15 Javascript
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
2010/08/16 Javascript
javascript数组详解
2014/10/22 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
js实现页面跳转的五种方法推荐
2016/03/10 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
2016/06/08 Javascript
AngularJs Forms详解及简单示例
2016/09/01 Javascript
jQuery实现简单的tab标签页效果
2016/09/12 Javascript
nodejs和php实现图片访问实时处理
2017/01/05 NodeJs
Bootstrap表单简单实现代码
2017/03/06 Javascript
Angular动画实现的2种方式以及添加购物车动画实例代码
2018/08/09 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
微信小程序授权登陆及每次检查是否授权实例代码
2019/09/18 Javascript
[55:03]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第二场 11.20
2020/11/20 DOTA
python中的yield使用方法
2014/02/11 Python
python脚本替换指定行实现步骤
2017/07/11 Python
Django中Forms的使用代码解析
2018/02/10 Python
python快速建立超简单的web服务器的实现方法
2018/02/17 Python
python实现决策树ID3算法的示例代码
2018/05/30 Python
python Dijkstra算法实现最短路径问题的方法
2019/09/19 Python
Pytest mark使用实例及原理解析
2020/02/22 Python
美国派对用品及装饰品网上商店:Shindigz
2016/07/30 全球购物
Mistine官方海外旗舰店:泰国国民彩妆品牌
2016/12/28 全球购物
美国最灵活的移动提供商:Tello
2017/07/18 全球购物
2014年乡镇妇联工作总结
2014/12/02 职场文书
Python代码实现双链表
2022/05/25 Python
前端canvas中物体边框和控制点的实现示例
2022/08/05 Javascript