原地址:http://blog.163.com/benben_long/blog/static/19945824320121225918434/

网络客户端:

1. 理解socket: socket是操作系统I/O系统的延伸部分,它扩展了操作系统的基本I/O到网络通信,使进程和机器之间的通信成为可能。建立 socket 需要通过调用 socket() 函数,并且还需要另外的调用来连接和激活它们( recv() 和 send() ) 。

2. 建立socket:首先需要建立一个实际的socket对象,其次需要把它连接到远程服务器上。建立socket对象的时候需要告诉系统两件事情:通信协议和协议家族。

通信协议:Internet通信类型基本上都是AF_INET,和 IPv4 对应。

协议家族:SOCK_STREAM ( TCP通信 ) 或 SOCK_DGRAM ( UDP通信 ) 。

TCP建立socket连接:

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

UDP建立socket连接:

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

3. 连接socket:一般需要一个tuple,包含远程主机名( 或IP地址) 和远程端口。

连接一个socket一般使用如下代码:

s.connect(( "www.example.com", 80))

由以上代码可看出,我们可以通过使用域名来连接远程主机,因为python为我们做了DNS解析。

http站点的的默认端口是80。python的socket库包含一个getservbyname()的函数可以自动查询服务器端口号列表。

该函数需要两个参数:协议名和端口名。

port = socket.getservbyname( "http", "tcp" )

注:getservbyname() 方法是直接调用操作系统API。

4. 从socket获取信息。

connect.py

 1 #!/usr/bin/env python
2 # Information Example
3  
4  import socket
5
6  print "Creating socket... "
7 s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
8  print "Done!"
9
10  print "Looking up port number... "
11 port = socket.getservbyname( "http", "tcp" )
12  print "Done!"
13
14  print "Connecting to remote host on port %d..." % port
15 s.connect(( "www.google.com", port ))
16  print "Done!"
17
18  print "Connected from ", s.getsockname()
19  print "Connected to ", s.getpeername()

运行结果:

可以看到,本次连接系统分配的端口号为2728,每次运行该程序此端口号一般不相同。

5. 利用socket通信。

python提供了两种通信方法:socket对象和文件类对象。

socket 对象提供了操作系统的 send(), sendto(), recv(), recvfrom() 调用的接口。

文件类对象则提供了 read(), write() readline() 等python接口。

文件类对象一般只对TCP连接工作得很好,对UDP连接反而不是很发。

6. 处理错误与socket异常。

与一般I/O和通信问题有关的 socket.error;

与查询地址信息有关的 socket.gaierror;

与其他地址错误有关的 socket.herror;

与在一个socket上调用settimeout()后,处理超时有关的socket.timeout。

7. UDP客户端和TCP客户端的区别。

<1>. 当socket建立的时候,程序调用的是 socket.SOCK_DGRAM ,而不是 SOCK_STREAM 。这会向操作系统提示socket将使用UDP通信,而不是TCP。

<2>. 对socket.getsevbyname()的调用寻找的是UDP端口,而不是TCP的。不是协议可使用同一端口号。

<3>. 程序没有办法探测服务器什么时候发送完数据。这是因为这里其实没有什么实际的连接。对connect()的调用只是初始化了一些内在参数。同时,服务器也 许不会返回任何数据,或者数据也许在传输过程中丢失,程序并没有智能地判断这个问题,因此,当结束等待传来的信息包时,需要按下Ctrl-C 。

网络服务器

1. 服务器的特点是等待来自客户端的请求,发送应答。与客户端类似,使用的是和客户端同样的socket接口,但建立socket的细节却是不同的。

2. 准备连接。

<1>. 建立socket对象。可以使用和客户端中使用的同一个socket对象。

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

<2>. 设置socket选项(可选)。

s.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )

<3>. 绑定到一个端口(同样,也可以是一个指定的网卡)。bind()函数第一个参数是你要绑定的IP地址,通常为空,意思是可以绑定到所有的接口和地址。

s.bind(( host, port ))

<4>. 侦听连接。唯一参数指明了服务器实际处理连接的时候,允许有多少个未决(等待)的连接在队列中等待。

s.listen(5)

3. 接受连接。

通常服务器连续运行的办法是小心地设计一个无限循环。

server.py

 1 #!/usr/bin/env python
2 # Base Server
3  
4  import socket
5
6 host = ''
7 port = 51423
8
9 s = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
10 s.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
11 s.bind((host, port))
12  print "Waiting for connections... "
13 s.listen(1)
14
15 while 1:
16 clientsock, cliendaddr = s.accept()
17 print "Got connection from ", clientsock.getpeername()
18 cliendsock.close()

这里的循环是:当你调用 accept() 的时候,它只在有一个客户端连接后才返回,同时程序会停止,并不使用任何CPU资源。

一个停止并等待输入或输出的程序称为被阻塞的程序。

测试此服务器程序可以使用操作系统的 telnet 指令。对于这个程序,先运行服务器,接着运行 telnet localhost 51423 。服务器程序会报告一个连接,并且 telnet 程序会立即终止。

4. 使用UDP。

在服务器端使用UDP,可以像使用TCP一样建立一个socket, 设置选项,并调用 blind() 函数。然而,不必使用 listen() 或 accept() 函数,仅仅使用 recvfrom() 函数就可以了。这个函数实际上会返回两个信息:收到的数据,以及发送这些数据的程序地址和端口号。

5. 避免死锁。

死锁发生在当一个服务器和客户端同时试图往一个连接上写东西和同时从一个连接上读的时候。在这些情况下,没有进程可以得到任何数据(如果它们都正在 读)。因此,如果它们正在写,向外的buffer会被充满,结果它们就好像是被骗了,什么都做不了。(解决?确保客户端每次执行完send()后进行一次 recv();简单地使客户端发送较少的数据;使用多线程,使客户端可以同时发送和接收。)小心地设计协议并适当地使用超时,可以把死锁出现的频繁和影响 减至最小。

《转》python 网络编程的更多相关文章

  1. Python 网络编程(二)

    Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...

  2. Python 网络编程(一)

    Python 网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...

  3. Python学习(22)python网络编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

  4. Day07 - Python 网络编程 Socket

    1. Python 网络编程 Python 提供了两个级别访问网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口 ...

  5. python网络编程-01

    python网络编程 1.socket模块介绍 ①在网络编程中的一个基本组件就是套接字(socket),socket是两个程序之间的“信息通道”. ②套接字包括两个部分:服务器套接字.客户机套接字 ③ ...

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

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

  7. Python网络编程基础pdf

    Python网络编程基础(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1VGwGtMSZbE0bSZe-MBl6qA 提取码:mert 复制这段内容后打开百度网盘手 ...

  8. python 网络编程(Socket)

    # from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...

  9. python 网络编程 IO多路复用之epoll

    python网络编程——IO多路复用之epoll 1.内核EPOLL模型讲解     此部分参考http://blog.csdn.net/mango_song/article/details/4264 ...

  10. 自学Python之路-Python网络编程

    自学Python之路-Python网络编程 自学Python之路[第一回]:1.11.2 1.3

随机推荐

  1. VS2008查看dll导出函数

    打开Visual Studio 2008 命令提示,使用命令 [plain] view plaincopyprint? dumpbin /exports simple.dll 即可查看

  2. 清华集训2014 day1 task2 主旋律

    题目 这可算是一道非常好的关于容斥原理的题了. 算法 好吧,这题我毫无思路,直接给正解. 首先,问题的正面不容易求,那么就求反面吧: 有多少种添加边的方案,使得这个图是DAG图(这里及以下所说的DAG ...

  3. 基于visual Studio2013解决面试题之1004最长等差数列

     题目

  4. DOM querySelector选择器

    原生的强大DOM选择器querySelector 在传统的 JavaScript 开发中,查找 DOM 往往是开发人员遇到的第一个头疼的问题,原生的 JavaScript 所提供的 DOM 选择方法并 ...

  5. C++数据结构之二叉树

    之前打算编算法类的程序,但是搞了几次英雄会后,觉得作为一个还在学习阶段的学生,实在是太浪费时间了,并不是没意义,而是我的基础还不牢固啊.所以转变了思路,这个学期打算分别用C++.Python.Java ...

  6. Qt图片显示效率的比较 转

    转http://blog.sina.com.cn/s/blog_5c70dfc80100r257.html 在Qt中处理图片一般都要用到QImage类,但是QImage的对象不能够直接显示出来,要想能 ...

  7. Control.Invoke和Control.BeginInvoke

    问题的引入 下面有个简单的demo,大家一看代码就知道效果如何示例.我新建一个winform的程序,然后写入了如下代码: using System; using System.Windows.Form ...

  8. Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法

    Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx" ...

  9. Android 环境变量配置(Mac)

    Mac 系统10.10,自带的就是jdk1.6,因为工作需要就升级到了1.7,要从新配置环境变量了 mac 默认是自带的有jdk1.6 安装路径为: /System/Library/Framework ...

  10. HotelIInventory项目小结

    最近参与了HotelIInventory这个项目的一个模块的开发.经验不足,对Sql脚本的编写能力还需要提高,这个模块的Sql语句大多是组长替我写的,如果靠我自己来写,我绝对是没有能力完成工作的,在此 ...