网络编程

一、客户端与服务器架构

硬件的客户端与服务器架构:打印机服务器,文件服务器

硬件服务器有关门的设备,打印机服务器有打印机,文件服务器NFS有磁盘。

软件的客户端与服务器架构:web服务器,数据库服务器,窗口服务器

软件服务器主要提供程序的运行,数据的发送与接收,合并,升级或其他的程序或数据的操作。

在完成服务之前,服务器必须要先完成一些设置。先要创建一个通讯端点,然服务器能“监听”请求。一单通讯端点创建好之后,我们在“监听”的服务器就可以进入他那等待和处理客户请求的无限循环中了。服务器准备好后,也要用之潜在的客户,让他们指导服务器已近准备好处理服务了,否则没有人会提请求的。

二、套接字:通信端点

套接字是一种具有之前所说的“通信端点”概念的计算机网络数据结构。套接字有两种,分别是基于文件型的和基于网络型的。

基于文件型的套接字家族有:AF_UNIX,基于网络的套接字家族有:AF_NETLINK和AF_INET。

三、python中的网络编程

1、socket()模块函数

要使用socket.socket()函数来创建套接字。其语法如下:

socket(socket_family,socket_type,protocol=0)

如前所述,socket _family 不是AF_UNIX就是AF_INET;socket_type可以是SOCK_STREAM或SOCK_DGREAM;protocol一般不填,默认值为0.

创建一个TCP/IP的套接字,你可以这样调用socket.socket():

tcpSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

同样的,创建一个UDP/IP的套接字,你要这样:

udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

由于socket模块中有太多的属性,我们在这里破例使用了’from module import *’语句。使用这个语句,我们就把socket模块里的所有属性都带到我们的命名空间里了,这样就能大幅度减短我们的代码。

tcpSocket = socket(AF_INET,SOCK_STREAM)

当我们创建了套接字对象后,所有的交互都将通过对该套接字对象的方法调用来进行。

3、创建一个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()函数就会返回一个单独的客户端套接字用于后续的通信。使用新的客户端套接字就想把客户的电话转接给一个客户服务人员。当一个客户打电话进来的时候,总计接了电话,然后把电话转接到合适的人那里处理客户的需求。

这样就可以空出总机,也就是最初的那个服务器套接字,于是,话务员就可以等待下一个电话(客户端的请求),与此同时,前一个客户与对应的客户服务人员在另一条线路上进行着他们之间的对话。同样的每当一个请求到来时,要创建一个新的端口,然后直接在哪个端口上与客户对话,这样就可以空出主端口来接受其他客户的链接。

在临时套接字创建好之后,通信就可以开始了。客户与服务器要使用这个新创建的套接字进行数据的发送与接收,直到通讯的某一方关闭了连接或发送了一个空字符串之后,通讯就结束了。

TCP时间戳服务器

[root@localhost opt]# cat -n tsTserv.py

1 #!/usr/bin/python

2

3 from socket import *

4 from time import ctime

5

6 HOST = ''

7 PORT = 21567

8 BUFSIZ = 1024

9 ADDR = (HOST,PORT)

10

11 tcpSerSock = socket(AF_INET,SOCK_STREAM)

12 tcpSerSock.bind(ADDR)

13 tcpSerSock.listen(5)

14

15 while True:

16     print 'waiting for onnection..'

17     tcpCliSock,addr = tcpSerSock.accept()

18     print '...connected from:',addr

19

20     while True:

21         data = tcpCliSock.recv(BUFSIZ)

22         if not data:

23             break

24         tcpCliSock.send('[%s] %s' %(ctime(),data))

25

26

27 tcpSerSock.close()

28

逐行解释

1~4行

第一行是Unix的启动信息行,随后我们导入了time.ctime()函数和socket模块的所有属性。

6~13行

HOST变量为空,表示bind()函数可以绑定在所有有效的地址上。我们还选用了一个随机生成的未被占用的端口号。在程序中,我们把缓冲区的大小设定为1K。你可以根据网络情况和应用的需要来修改这个大小。listen()函数的参数只是表示最多允许多少个连接同时连进来,而后来的连接就会被拒绝掉。

TCP服务器的套接字(tcpSerSock)在第11行被生成。随后把套接字绑定到服务器的地址上,然后开始TCP监听。

15~28行

在进入到服务器的无限循环后,我们被动地等待连接的到来。当有连接时,我们进入对话循环,等待客户端发送数据。如果消息为空,表示客户端已经推出,那就再去等待下一个客户端连接。得到客户端消息后,我们在消息前加一个时间戳后返回。最后一行不会被执行到,放在这里用于提醒我们,在服务器退出的时候,要记得调用close()函数。

4、创建TCP客户端

我们也创建一个代码框架

cs = socket()                           # 创建客户端套接字

cs.connect()                           #尝试连接服务器

comm_loop:                           #通信循环

cs.send()/cs.recv()                   #对话(发送、接收)

cs.close()                              #关闭客户端套接字

如前所述,所有的套接字都由socket.socket()函数创建。在客户端有了套接字之后,马上就可以调用connet()函数去连接服务器。连接建立后,就可以与服务器开始对话了。在对话结束之后,客户端就可以关闭套接字

[root@localhost opt]# cat -n tsTchlnt.py

1 #!/usr/bin/python

2 from socket import *

3

4 HOST = 'localhost'

5 PORT = 21567

6 BUFSIZE = 1024

7 ADDR = (HOST,PORT)

8

9 tcpCliSock = socket(AF_INET,SOCK_STREAM)

10 tcpCliSock.connect(ADDR)

11

12 while True:

13     data = raw_input('>')

14     if not data:

15         break

16     tcpCliSock.send(data)

17     data = tcpCliSock.recv(BUFSIZ)

18     if not data:

19         break

20     print data

21

22 tcpCliSock.close()

5~11行

HOST和PORT变量表示服务器的主机名由于我们在同一台电脑上进行测试,所以HOST里放的是本机的主机名(如果你的服务器运行在其它电脑上,要做相应的修改)。端口号与服务器上设置的端口号完全相同。缓冲区大小还是设为1K。

TCP客户套接字(tcpCliSock)在第10行创建。然后就去连接服务器。

13~23行

客户端也有个无限循环,但这跟服务器的那个不期望推出的无限循环不一样。客户端的循环在以下两个条件的任意一个发生后就退出:用户没有输入任何内容(14~16行)或 服务器由于某种原因退出,导致recv()函数失败(18~20行)。否则,在一般情况下,客户端会把用户输入的字符串发给服务器进行处理,然后接收并显示服务器传来的加了时间戳的字符串。

5、运行我们的客户端与TCP服务器

先执行服务端的脚本,先启动服务器

[root@localhost opt]# ./tsTserv.py

waiting for onnection..

...connected from: ('127.0.0.1', 58318)

再执行客户端的脚本,与服务器建立连接

[root@localhost opt]# ./tsTchlnt.py

>wulil

[Mon Feb 22 16:02:49 2016] wulil

>wowo

[Mon Feb 22 16:02:50 2016] wowo

>li

[Mon Feb 22 16:02:53 2016] li

>

6、创建一个UDP服务器

由于UDP服务器不是面向连接的,所以不用像TCP服务器那样做那么多设置工作。事实上,并不用设置什么,直接等待近来的链接就好了。

ss = socket()                #创建服务器套接字

ss.bind()                   #绑定服务器套接字

inf_loop:                   #服务器无限循环

cs = ss.recvfrom()/ss.sendto()#对话(接收与发送)

ss.close()                   #关闭服务器套接字

从伪代码中可以看出,使用的还是那套先创建套接字然后绑定到本地地址(主机/端口)的方法。无限循环中包含了从客户端接收消息,返回加了时间戳的结果和回去等写一个消息这三步。同样的,由于代码不会跳出无限循环,所以,close()函数调用是可选的。我们这一句话的原因在于提醒开发人员,在设计的时候能够设计一个更智能的退出方案,要确保close()函数会被调用。

服务器端

[root@localhost opt]# cat -n tsUserv.py

1 #!/usr/bin/python

2 from socket import *

3 from time import ctime

4

5 HOST = ''

6 PORT = 21567

7 BUFSIZ = 1024

8 ADDR = (HOST,PORT)

9

10 udpSerSock = socket(AF_INET,SOCK_DGRAM)

11 udpSerSock.bind(ADDR)

12

13 while True:

14     print 'waiting for meassage..'

15     data,addr = udpSerSock.recvfrom(BUFSIZ)

16     udpSerSock.sendto('[%s] %s' %(ctime(),data),addr)

17     print '...received from and returned to :',addr

18

19 udpSerSock.close()

客户端

[root@localhost opt]# cat -n tsUclnt.py

1 #!/usr/bin/python

2 from socket import *

3

4 HOST = 'localhost'

5

6 PORT = 21567

7 BUFSIZ = 1024

8 ADDR = (HOST,PORT)

9

10

11 udpCliSock = socket(AF_INET,SOCK_DGRAM)

12

13 while True:

14     data = raw_input('>')

15     if not data:

16         break

17     udpCliSock.sendto(data,ADDR)

18     data,ADDR = udpCliSock.recvfrom(BUFSIZ)

19     if not data:

20         break

21     print data

22

23 udpCliSock.close()

[root@localhost opt]# ./tsUserv.py

waiting for meassage..

...received from and returned to : ('127.0.0.1', 43523)

waiting for meassage..

...received from and returned to : ('127.0.0.1', 45046)

waiting for meassage..

...received from and returned to : ('127.0.0.1', 45046)

waiting for meassage..

[root@localhost opt]# ./tsUclnt.py

>iiii

[Tue Feb 23 14:08:30 2016] iiii

>lll

[Tue Feb 23 14:08:32 2016] lll

>kk

[Tue Feb 23 14:25:51 2016] kk

四、SocketServer模块

创建SocketServeTCP服务器

[root@localhost opt]# cat -n TsTservss.py

1 #!/usr/bin/python

2

3 from SocketServer import (TCPServer as TCP,StreamRequestHandler as SRH)

4 from time import ctime

5

6 HOST = ''

7 PORT = 21567

8 ADDR = (HOST,PORT)

9

10 class MyRequestHandler(SRH):

11     def handle(self):

12         print '...connected from:',self.client_address

13         self.wfile.write('[%s] %s' % (ctime(),self.rfile.readline()))

14

15 tcpServ = TCP(ADDR,MyRequestHandler)

16 print 'waiting for connection...'

17 tcpServ.serve_forever()

[root@localhost opt]# cat -n TsTclntss.py

1 #!/usr/bin/python

2

3 from socket import *

4

5 HOST = 'localhost'

6 PORT = 21567

7 BUFSIZ = 1024

8 ADDR = (HOST,PORT)

9

10 while True:

11     tcpCliSock = socket(AF_INET,SOCK_STREAM)

12     tcpCliSock.connect(ADDR)

13     data = raw_input('>')

14     if not data:

15         break

16     tcpCliSock.send('%s\r\n' % data)

17     data = tcpCliSock.recv(BUFSIZ)

18     if not data:

19         break

20     print data.strip()

21

运行服务器脚本

[root@localhost opt]# ./TsTservss.py

waiting for connection...

...connected from: ('127.0.0.1', 58325)

...connected from: ('127.0.0.1', 58326)

...connected from: ('127.0.0.1', 58327)

...connected from: ('127.0.0.1', 58328)

运行客户端脚本

[root@localhost opt]# ./TsTclntss.py

>ll

[Tue Feb 23 16:26:18 2016] ll

>mm

[Tue Feb 23 16:26:19 2016] mm

>kk

[Tue Feb 23 16:26:21 2016] kk

>

本文转自aaa超超aaa 51CTO博客,原文链接:http://blog.51cto.com/10983441/1744385

Python网络编程1--笔记相关推荐

  1. python网络编程学习笔记(二)

    python网络编程学习(四) 多用途客户端协议 一.ftp 功能:上传下载文件,删除命名文件,建立删除目录,自动压缩,保存目录 1.代码: #coding=utf-8 '''连接远程ftp服务器,显 ...

  2. python网络编程需要学什么,python网络编程学习笔记(五):socket的一些补充 Python 网络编程需要学习哪些网络相关的知识...

    python的socket编程问题hdr = recvall(s, 5) if hdr is None: print 'Unexpected EOF receivingstruct在unpack的时候 ...

  3. Python 网络编程学习笔记(二)——DNS 域名解析客户端程序设计

    本博文介绍如何使用 Python 网络编程,设计并实现客户端的 DNS 域名解析及缓存服务. 1 基本概念 域名系统(DNS)是一个庞大的.全球的分布式数据库,,它主要用来把主机名转换成 IP 地址, ...

  4. python网络编程学习笔记(4):域名系统

    转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 一.什么是域名系统 DNS 计算机域名系统 (DNS) 是由解析器以及域名服务器组成的.当我们在上网的时候,通常输 ...

  5. python网络编程学习笔记(6):Web客户端访问

    转载请注明:@小五义http://www.cnblogs.com/xiaowuyi 6.1 最简单的爬虫 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.pyt ...

  6. python网络编程证书_《Python网络编程基础》笔记

    python网络编程基础 ================== Author: lujun9972 Date: 2013-03-08 22:29:20 CST Table of Contents == ...

  7. python 谷歌地图api_《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档...

    Foundations of Python Network Programing,Third Edition <python网络编程>,本书中的代码可在Github上搜索fopnp下载 本 ...

  8. 读书笔记 - -《Python网络编程》重点

    文章目录 一.前言 二.客户/服务器网络编程简介 三.UDP 3.1 端口号 3.2 套接字 3.3 UDP分组 3.4 小结 四.TCP 4.1 TCP工作原理 4.2 绑定接口 4.3 死锁 4. ...

  9. [转载] PYTHON 网络编程

    参考链接: Python | 使用openpyxl在Excel文件中进行三角运算 Socket 编程实战 文章目录 Socket库 0.1. 什么是 Socket? 0.2. socket()函数 0 ...

  10. python网络编程--socket简单实现

    python网络编程                                                                                           ...

最新文章

  1. linux 文件拷贝并替换,Linux_cmd replace 文件替换使用说明,帮助信息: 复制代码 代码如 - phpStudy...
  2. [解答] python下如何安装SocketServer?
  3. 互联网架构阶段 数据库读写分离 Amoeba
  4. Spring 用注解Annotation注入 abstract 抽象父类的属性
  5. (四)Struts2 架构
  6. 使用Zapier将应用程序与Neo4j集成
  7. pae扩展内存 linux,Linux内核-内存管理-PAE(物理地址扩展)
  8. android音乐播放器案例,Android MediaPlayer实现音乐播放器实例代码
  9. 日常开发需要掌握的Maven知识
  10. 求高人指点此分页存储过程怎么样?
  11. 抓肇事车(入门级算法)(C语言)
  12. 如何解决使用PCS7时报警无法确认的问题?
  13. 高通CAMERA 调试
  14. BitTorrent协议分析一
  15. webim--web端即时通讯的实现
  16. proxychains DNS解析失败问题
  17. CHUA 返回的矢量的长度为 3,但初始条件矢量的长度为 4。CHUA 返回的矢量和初始条件矢量的元素数目必须相同。
  18. [GUI] 图片背景是黑色的,在unity中怎么变成透明
  19. 虫洞 Wormhole
  20. System.StackOverflowException

热门文章

  1. Tomcat配置Jconsole , JvisualVm 监控配置
  2. Linux文本比较命令:diff
  3. PHP 4.4.7 中用 PEAR 类库操作 ZIP 压缩文件
  4. 重写toString()
  5. mysql开启skip-name-resolve 导致root@127.0.0.1(localhost)访问引发的ERROR 1045 (28000)错误解决方案...
  6. 工作后越来越觉得,丢什么也不能丢账号!
  7. SpringMVC过程中@RequestBody接收Json的问题 总是报415
  8. 《Python数据分析与挖掘实战》读书笔记
  9. org.apache.log4j.Logger详解
  10. SSM项目搭建一(终)