首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

python 网络编程学习 - 一

2012-11-18 
python 网络编程学习 - 1?参考:http://www.cnblogs.com/cacique/archive/2012/08/05/2623995.html?套接字

python 网络编程学习 - 1

?

参考:http://www.cnblogs.com/cacique/archive/2012/08/05/2623995.html

?

套接字
首先,我们应先理解什么事套接字。套接字是一种具有之前所说的“通信端点”概念的计算机网络数据结构。网络化的应用程序在开始任何通讯之前都必须要创建套接字。就像电话的插口一样,没有它就没办法通信。
套接字有两种,分别是基于文件型的和基于网络型的。
套接字家族包括AF_UNIX,AF_LOCAL,AF_INET和AF_NETLINK。
python只支持AF_UNIX,AF_INET和AF_NETLINK。因我们只关心网络编程,所以我们只用AF_INET。

SOCKET()模块

套接字模块是一个非常简单的基于对象的接口,它提供对低层BSD套接字样式网络的访问。使用该模块可以实现客户机和服务器套接字。要在python 中建立具有TCP和流套接字的简单服务器,需要使用socket模块。利用该模块包含的函数和类定义,可生成通过网络通信的程序。
socket内建方法

函数?描述服务器端套接字函数s.bind()??绑定地址(主机,端口号对)到套接字s.listen()开始TCP 监听s.accept()??被动接受TCP 客户的连接,(阻塞式)等待连接的到来客户端套接字函数s.connect()主动初始化TCP 服务器连接s.connect_ex()connect()函数的扩展版本,出错时返回出错码,而不是抛异常公共用途的套接字函数s.recv()接收TCP 数据s.send()发送TCP 数据s.sendall()完整发送TCP 数据s.recvfrom()接收UDP 数据s.sendto()发送UDP 数据s.getpeername() ???连接到当前套接字的远端的地址s.getsockname()当前套接字的地址s.getsockopt() ???返回指定套接字的参数s.setsockopt() ???设置指定套接字的参数s.close()关闭套接字面向模块的套接字函数s.setblocking()?设置套接字的阻塞与非阻塞模式s.settimeout()a设置阻塞套接字操作的超时时间s.gettimeout()a得到阻塞套接字操作的超时时间面向文件的套接字的函数s.fileno()套接字的文件描述符s.makefile() ???创建一个与该套接字关连的文件a. Python 2.3 版本新加入的函数

连接方式分TCP和UDP两种

分别看一下
TCP方式
server端
server端的socket一般流程是这样:
?? ?1.?? ?建立一个socket(可以选择socket类型INET,UNIX等,以及连接方式TCP/UDP)

????????socket=socket.socket(familly,type)
??????? family的值可以是AF_UNIX(Unix域,用于同一台机器上的进程间通讯),也可以是AF_INET(对于IPV4协议的TCP和 UDP),至于type参数,SOCK_STREAM(流? 套接字)或者 SOCK_DGRAM(数据报文套接字),SOCK_RAW(raw套接字)。

?? ?2.?? ?使用bind公开一个端口,使得client可以方便连接

????????socket.bind(address)

??????? address必须是一个双元素元组,((host,port)),主机名或者ip地址+端口号。如果端口号正在被使用或者保留,或者主机名或ip地址错误,则引发socke.error异常。
?? ?3.?? ?设置一个listen队列的大小

????????socket.listen(backlog)
??????? backlog指定了最多连接数,至少为1,接到连接请求后,这些请求必须排队,如果队列已满,则拒绝请求。
?? ?4.??? 服务器套接字通过socket的accept方法等待客户请求一个连接:

    connection,address=socket.accept()


    调用accept方法时,socket会进入'waiting'(或阻塞)状态。客户请求连接时,方法建立连接并返回服务器。accept方法返回 一个含有俩个元素的元组,

    形如(connection,address)。第一个元素(connection)是新的socket对象,服务器通过它与客 户通信;第二个元素(address)是客户的internet地址。
?? ?5.?? ?通过send()/recv()来对socket进行读写操作

    服务器调用send,并采用字符串形式向客户发送信息。send方法 返回已发送的字符个数。服务器使用recv方法从客户接受信息。调用recv时,必须指定一个整数来控制本次调用所接受的最大数据量。recv方法在接受 数据时会进入'blocket'状态,最后返回一个字符串,用它来表示收到的数据。如果发送的量超过recv所允许,数据会被截断。多余的数据将缓冲于接 受端。以后调用recv时,多余的数据会从缓冲区删除。

代码示例

python 网络编程学习 - 一
import sockets=socket.socket()s.bind(('xxx.xxx.xxx.xxx',xxxx))    #ip地址和端口号s.listen(5)cs,address = s.accept()print 'got connected from',addresscs.send('byebye')ra=cs.recv(512)print racs.close()
python 网络编程学习 - 一



client端

  1. ??? 创建一个socket以连接服务器 socket=socket.socket(family,type)
  2. ??? 使用socket的connect方法连接服务器 socket.connect((host,port))
  3. ??? 客户和服务器通过send和recv方法通信。
  4. ??? 结束后,客户通过调用socket的close方法来关闭连接。


代码示例

import sockets=socket.socket()s.connect(('xxx.xxx.xxx.xxx',xxxx))   #与服务器程序ip地址和端口号相同data=s.recv(512)s.send('hihi')s.close()print 'the data received is',data


测试代码

服务器端

?

python 网络编程学习 - 一
#!/usr/bin/python# -*- coding: utf-8 -*-import socketfrom time import ctime'''host为空表示bind可以绑定到所有有效地址上port 必须要大于1024bufsiz为缓冲区 我们设置为1K'''host = ''  port = 23456bufsiz = 1024ADDR = (host,port)tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)   #参数表示允许多少连接同时连进来try:    while True:        '''        进入服务器的无限循环中,等待连接到来        有链接时,进入对话循环,等待客户发送数据,如果消息为空,表示客户端已经退出,等待下一个客户端连接        得到客户端消息后在消息前加一个时间戳后返回        '''        print 'waiting for connection...'        tcpSerSock,addr = tcpSerSock.accept()        print '...connected from ',addr        while True:            data = tcpSerSock.recv(bufsiz)            if not data:                break            tcpSerSock.send('[%s] %s' %(ctime(),data))except BaseException, e:    tcpSerSock.close()  #记住在服务器退出时记得关闭
python 网络编程学习 - 一

?

客户端

python 网络编程学习 - 一
#!/usr/bin/python# -*- coding: utf-8 -*-import sockethost = '127.0.0.1'  port = 23456bufsiz = 1024ADDR = (host,port)tcpCliSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcpCliSock.connect(ADDR)while True:    data = raw_input('> ')    if not data:        break    tcpCliSock.send(data)    data = tcpCliSock.recv(bufsiz)    if not data:        break    print datatcpCliSock.close()
python 网络编程学习 - 一


UDP方式
UDP号称无连接传输,全然没有TCP那么复杂,三次握手,错误重传之类的机制都没有,发的只管发,收得只管收,收到没有?不知道,顺序不对怎么 办?不管!就是这样,但是速度就要比TCP高得多了。在对数据帧要求不是很高的地方,这确实是很好用的,比如网络上的视频传输,音频传输等。

server端
?? ?1.?? ?建立数据报形式的socket
?? ?2.?? ?公开一个端口,一边客户端连接
?? ?3.?? ?开始接收数据

python 网络编程学习 - 一
    def udpServer():          address = ('xxx.xxx.xxx.xxx', xxxx)          srvsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)          srvsock.bind(address)          #data,addr = srvsock.recvfrom(2048)            if __name__ == "__main__":          udpServer()  
python 网络编程学习 - 一

server中address元组中的引号表示可以接受任何地址来的数据报,TCP例子中的则表示可以接受任意地址发起的连接。

client端
?? ?1.?? ?新建一个数据报socket
?? ?2.?? ?收发数据

python 网络编程学习 - 一
    def udpClient():          address = ('xxx.xxx.xxx.xxx', xxxx)          clisock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)          #clisock.sendto(data, address)                if __name__ == "__main__":          udpClient()  
python 网络编程学习 - 一

?

测试代码

服务器端

?

python 网络编程学习 - 一
#!/usr/bin/python# -*- coding: utf-8 -*-import socketfrom time import ctime'''host为空表示bind可以绑定到所有有效地址上port 必须要大于1024bufsiz为缓冲区 我们设置为1K'''host = ''  port = 23456bufsiz = 1024ADDR = (host,port)udpSerSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)udpSerSock.bind(ADDR)try:    while True:        print 'waiting for connection...'        data,addr = udpSerSock.recvfrom(bufsiz)        udpSerSock.sendto('[%s] %s' %(ctime(),data),addr)        if data == 'exit':            break        print '...received from and returned to:',addrexcept BaseException, e:    print e    udpSerSock.close()
python 网络编程学习 - 一

?

客户端

python 网络编程学习 - 一
#!/usr/bin/python# -*- coding: utf-8 -*-import sockethost = '127.0.0.1'  port = 23456bufsiz = 1024ADDR = (host,port)udpCliSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)while True:    data = raw_input('> ')    if not data:        break    udpCliSock.sendto(data,ADDR)    data,ADDR = udpCliSock.recvfrom(bufsiz)    if not data:        break    print dataudpCliSock.close()
python 网络编程学习 - 一

?

?

?

参考链接:http://www.iteye.com/topic/401391

?

     http://www.cppblog.com/lai3d/archive/2008/02/19/42919.html

热点排行