Python 网络编程

1.客户端/服务器网络编程

  在完成服务前,服务器必需先完成的设置:先创建一个通讯端点(套接字),让服务器能监听请求。

  生活例子:服务器相当于公司总线电话,通讯端点相当于电话的插口,电话要通过插口才能与外界联系。

  客户端的设置:只要创建一个通讯端点,建立到服务器的连接,然后客户端就可以提出请求了,请求可以包括数据交互,一旦请求处理完成,客户端收到了结果,通信就结束了。

 

2.面向连接与无连接

  面向连接(TCP/IP):在通信前一定要建立一条连接,每一个要发送的信息可能会被查分成多份,到达目的地后按顺序拼接起来,传给正在等待的应用程序。顺序、可靠、不会重复

  无连接(UDP/IP):无需建立连接就可以通讯,数据是整个发送,数据到达的顺序、可靠性及不重复性无法保证,没有要维持线路连接的额外负担。性能好、便宜。

 

3.套接字地址:addr=(host,port)  主机与端口

  如把套接字比做电话的接口,那套接字地址的主机与端口就像区号与电话号码的一对组合。如电话0771-6518123 ,要打给谁(6518123),往哪打(0771)。

  合法的端口号范围为0~65535,小于1024的为系统保留端口

 

4.socket

  socket又称“套接字”,应用程序通常通过“套接字”向网络发出请求或者应答网络请求

  socket.socket(socket_family,socket_type,protocal)

    family:套接字家族可以是AF_UNIX或者AF_INET(指定IPV4家族)

    type:套接字类型可以是SOCK_STREAM(面向连接)或SOCK_DGRAM(无连接)

    protocal:一般不填默认为0

  socket对象方法:

 1 from socket import *
 2 
 3 #服务器套接字
 4 s.bind(addr)    #将套接字与套接字地址绑定,在AF_INET下,以元组(host,port)的形式表示地址addr
 5 s.listen(backlog)    #开始TCP监听,backlog指定最大连接数,至少为1,大部分为5
 6 s.accept()    #被动接受TCP客户端连接,阻塞式等待连接的到来
 7 
 8 #客户端套接字
 9 s.connect(addr)    #主动初始化与TCP服务器连接,以元组(host,port)的形式表示地址addr
10 
11 #公共用途的套接字函数
12 s.recv(bufsize)    #接收TCP数据,字符串返回,bufsize指定要接收的最大数据量
13 s.send(data)    #发送TCP数据,将string中的数据发送到连接的套接字,返回发送的字节数
14 s.sendall(data)    #完整发送TCP数据成功返None,失败则抛异常
15 s.close()    #关闭套接字
16 s.recvfrom(bufsize)    #接收UDP数据,返回(data,address)数据和发送数据的套接字地址
17 s.sendto(data,addr)    #发送UDP数据,返回发送的字节数
18 s.getpeername()    #返回连接套接字的远程地址,(ipaddr,port)ip地址和端口号
19 s.getsockname()    #返回套接字自己的地址,(ipaddr,port)
View Code

 

5.TCP/IP

通用TCP服务器伪代码:

1 ss = socket()    #创建服务器套接字
2 ss.bind()    #把地址绑定到套接字上
3 ss.listen()    #监听连接
4 inf_loop:    #服务器无限循环
5     cs = ss.accept()    #接收客户端连接
6     comm_loop:    #通信循环
7         cs.recv()/cs.send()    #对话(接收与发送)
8     cs.close()    #关闭客户端套接字
9 ss.close()    #关闭服务器套接字(可选)

创建一个服务器:能够接收客户端的消息,在消息前加一个时间戳后返回

 1 from socket import *
 2 from time import ctime
 3 
 4 def server():
 5     "接收客户端的消息,在消息前加一个时间戳后返回"
 6     
 7     host = "localhost" #本地主机名
 8     port = 9999 #端口号
 9     bufsize = 1024 #设缓冲区大小为1K
10     addr = (host,port) #套接字地址
11     tcpSerSock = socket(AF_INET,SOCK_STREAM) #创建服务器套接字,IPV4面向连接
12     tcpSerSock.bind(addr)    #绑定套接字地址
13     tcpSerSock.listen(5)    #指定等待连接最大数
14     
15     while True:        #服务器无限循环
16         print("等待连接------------------->")
17         (tcpCliSock,addr) = tcpSerSock.accept()    #接收客户端连接,返回客户端套接字和客户端套接字地址
18         print("连接来自:",addr)
19         
20         while True:        #通信循环
21             data = tcpCliSock.recv(bufsize)    #接收客户端发来的数据
22             if not data: #如果没有数据了退出通信循环
23                 break
24             tcpCliSock.send( ('[%s]%s' % (ctime(),data.decode('utf-8'))).encode('utf-8') ) #把要发送的数据全部编码
25         tcpCliSock.close()    #关闭客户端套接字
26     
27 if __name__=='__main__':
28     server()
View Code

 

通用TCP客户端伪代码:

1 cs = socket()    #创建客户端套接字
2 cs.connect()    #尝试连接服务器
3 comm_loop:    #通信循环
4     cs.send()/cs.recv()    #对话(发送和接收)
5 cs.close()    #关闭客户端套接字(可选)

创建一个客户端:给服务器发送消息并接收消息

 1 from socket import *
 2 
 3 def client():
 4     host = 'localhost'    #本地主机名
 5     port = 9999    #要与服务器端口一致
 6     bufsize = 1024    #接收数据大小 1K
 7     addr = (host,port)    #客户端套接字地址
 8     tcpCliSock = socket(AF_INET,SOCK_STREAM)    #创建客户端套接字,IPV4面向连接
 9     tcpCliSock.connect(addr)    #连接服务器
10     
11     while True:        #通信循环
12         data = input('输入要发送的信息-->')    #等待用户输入要发送的信息
13         if not data: #如果没有要发送的数据直接退出通信循环
14             break
15         tcpCliSock.send(data.encode('utf-8')) #发送信息
16         data = tcpCliSock.recv(bufsize)    #接收服务器返回的消息
17         if not data: #如果没有数据了退出通信循环
18             break
19         print(data.decode('utf-8'))
20     tcpCliSock.close()    #关闭客户端套接字
21     
22 if __name__=='__main__':
23     client()
View Code

 

服务器端:

客户端:

 

 6.UDP/IP

通用UDP/IP服务器伪代码:

1 ss = socket()    #创建服务器套接字
2 ss.bind()    #绑定服务器套接字地址
3 inf_loop:    #服务器无限循环
4     cs = ss.recvfrom()/ss.sendto()    #对话
5 ss.close()    #可选 关闭服务器套接字

服务器:

 1 from socket import *
 2 from time import ctime
 3 
 4 def udpServer():
 5     "接收客户端的消息,在消息前加一个时间戳后返回"
 6     host = 'localhost'    
 7     port = 8888
 8     bufsize = 1024    #接收数据大小    1K
 9     addr = (host,port)    #服务器套接字地址
10     udpSerSock = socket(AF_INET,SOCK_DGRAM)    #创建服务器套接字,IPV4无连接
11     udpSerSock.bind(addr)    #绑定套接字地址
12     
13     while True:        #服务器无限循环
14         print('等待消息------------>')
15         (data,addr) = udpSerSock.recvfrom(bufsize)    #接收数据
16         data.decode('utf-8')    #对接收的数据解码
17         udpSerSock.sendto( ('[%s]%s' % (ctime(),data)).encode('utf-8') ,addr)    #对数据进行编码再发送
18         print('收到来自(%s)的消息并返回' % (addr,))
19     
20 if __name__=='__main__':
21     udpServer()
View Code

通用UDP/IP客户端伪代码:

1 cs = socket()    #创建客户端套接字
2 comm_loop:    #通信循环
3     cs.sendto()/cs.recvfrom() #对话
4 cs.close    #关闭套接字

客户端:

 1 from socket import *
 2 
 3 def udpClient():
 4     host = 'localhost'
 5     port = 8888 #必须与服务器一致
 6     bufsize = 1024 #接收数据大小    1K
 7     addr = (host,port)    #套接字地址
 8     udpCliSock = socket(AF_INET,SOCK_DGRAM)    #IPV4无连接
 9     
10     while True:        #通信循环
11         data = input('输入要发生的信息--------->')
12         if not data:    #没有信息则退出通信循环
13             break
14         udpCliSock.sendto(data.encode('utf-8'),addr)    #向服务器发送数据
15         (data,addr) = udpCliSock.recvfrom(bufsize)    #接收服务器发来的数据
16         if not data:    #没有数据则退出循环
17             break
18         print(data.decode('utf-8'))
19     udpCliSock.close()
20     
21 if __name__=='__main__':
22     udpClient()
23     
View Code

服务器:

客户端:

 

7.文件传输协议(FTP)

工作流程:

1.客户端连接远程的FTP服务器

2.客户端输入用户名和密码(或“匿名”和电子邮件地址)

3.客户端做各种文件传输和信息查询操作

4.客户端退出远程FTP服务器,结束通讯

因特网上的FTP客/服模式都使用两个套接字来通讯:一个是控制和指令端口21号端口)发送FTP协议,而数据通过数据端口(有时是20号端口)传输。

说有时是因为FTP有两种模式:主动和被动。只有在主动模式,服务器才使用数据端口,服务器主动连接客户端的数据端口。在被动中,服务器告诉客户端随机端口号,由客户端主动建立数据连接。

使用FTP:需导入ftplib模块,并实例化一个ftplib.FTP类对象,所有的FTP操作都要使用这个对象来完成

ftplib.FTP类方法:

 1 login(user='',passwd='',acct='')    #登陆到FTP服务器,所有参数可选
 2 pwd()    #得到当前工作目录
 3 cwd(path)    #把当前工作目录设置为path
 4 dir([path[,cb]])    #显示path目录里的内容,cb可选是一个回调函数
 5 nlst([path])    #与dir()类似,但返回一个文件名的列表,而不是显示这些文件名
 6 retrlines(cmd,[,cb])    #给定FTP命令,用于下载文本文件,可选cb处理文件每一行
 7 retrbinary(cmd,cb[,bs=8192])    #用于下载二进制文件,每一块8K(8192=8*1024)
 8 storlines(cmd,f)    #上传文本文件,要给定一个文件对象f
 9 storbinary(cmd,f[,bs=8192])    #上传二进制文件,文件块大小默认8K
10 rename(old,new)    #把远程文件old改名new
11 delete(path)    #删除位于path的远程文件
12 mkd(directory)    #创建远程文件
13 rmd(directory)    #删除远程目录
14 quit()    #关闭连接并退出
View Code

 

 

8.网络新闻传输协议(NNTP)

供用户在新闻组中下载或发表帖子的方法

1.连接到服务器

2.登陆(可选,根据NNTP服务器的配置)

3.发送请求

4.退出

一般来说,在登陆完成后,要调用group()方法来选择一个感兴趣的新闻组。方法返回服务器的返回信息、文章的数量、第一个和最后一个文章的ID和组的名字。有了这些信息后,就可做一些操作,如看文章、下载帖子或发表文章

nntplib.NNTP类

posted @ 2019-07-07 14:57  北风吹沙  阅读(197)  评论(0编辑  收藏  举报