1.网络协议
网络协议是网络中进行数据交换与传输所需的规则、标准或约定,得到实用主要由语法(数据与信息的结构形式)、语义和同步(事件的实现顺序)三个要素组成。
世界上最先提出的协议理论模型是由国际标准组织(ISO)提出的开放系统互联基本参考模型(OSI),它采用的是七层协议的体系结构。虽然OSI清晰完整,但终因复杂又不实用而没有得到实用。另一方面,使用了简化的OSI的TCP/IP协议却得到了非常广泛的应用,它是一个四层的体系结构,包括应用层、运(传)输层、网际(络)层和网络接口层。
应用层 (FTP、SMTP、HTTP等) |
传输层 (TCP、UDP) |
网络层 (IP) |
网络接口层
|
TCP/IP协议图
TCP/IP协议其实是一个协议簇,不仅包括TCP和IP协议,还包括UDP、FTP、HTTP、SMTP等,此外还包括一些图中没显示的ICMP、ARP、RARP等协议。
这种分成的协议结构还表示出,上层协议需要传输的数据,应该交给它紧邻的下层。而应用层和传输分别有两个以上的协议,所以对于应用层来说,不同的协议数据可以通过传输层的不同协议来传输。
2、socket 模块
TCP/IP 协议中的 TCP 和 UDP 协议都通一种名为套接字(socket)来实现网络功能。套接字是一种类文件对象,它使程序能够接受客户端的连接或建立对客户端的连接,用以发送和接收数据。无论是客户端程序还是服务器端程序,为了进行网络通信,都要创建套接字对象。
在 Python 标准库中,使用 socket 模块中提供的 socket 对象,可以在计算机网络中建立服务器与客户端,并且能够进行通信。服务器端需要建立一个 socket 对象,并等待客户端的连接。客户端使用 socket 对象与服务器端进行连接,一旦连接成功,客户端和服务端就可以进行通信了。
socket 模块中的 socket 对象是 socket 网络编程的基础对象,其初始化原型
socket(family,type,proto)
其参数含义:
family:地址族,可选参数。默认AF_INET(IPv4),也可以是AF_INET6 或者是 AF_UNIX;
type:socket 类型,可选参数。默认SOCK_STREAM(TCP协议),可用SOCKET_DGRAM(UDP协议);
proto:协议类型,可选参数。默认为0。
作为服务器端的 socket 对象主要应用以下常用方法:
1.bind(address)
其参数 address 是由IP地址和端口组成的元组,如‘('127.0.0.1', 1051)’ 。如果IP地址为空,则表示本机。它的作用是使用socket和服务器地址相关联。
2.listen(backlog)
参数backlog指定在拒接连接之前,操作系统允许它的最大挂起连接数量。最小值为0(如果用户使用了更小的值,则会自动被置为0),大部分程序最多设置为5就足够了。
该方法将socket设置为服务器模式,之后就可以电泳一下的accept()方法等待客户端的连接。
3.accept()
它会等待进入的连接,并返回一个由新建的与客户端的socket连接和客户端地址组成的元组,而客户的地址也是一个由客户端IP地址和端口组成的元组。
4.close()
这个方法的作用就是关闭该socket。停止本程序与服务器或客户端的连接。
5.recv(buffersize[,flag])
用于接受远程连接发来的信息,并返回该信息,其类型为bytes。buffersize可以设定缓冲区的大小。
6.send(data[,flags])
用于向连接的远端发送信息,data应该是bytes类型的数据。其返回值为一已传送的字节数。其传输的数据长度有一定的限度。
7.sendall(data[,flags])
这个方法与send()方法相似,但是有时候在传输数据时,由于数据过多,用send()方法无法一次性传输,用sendall()方法可以解决这一问题,而sendall()也是通过循环运行send()方法来进行传输。
而建立服务器端的socket就要依次使用这几个方法,其基本顺序为:
3.创建一个服务器端
1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 import socket 4 5 sk = socket.socket() #创建socket对象 6 address = ('127.0.0.1', 8001) 7 sk.bind(address) #绑定本机地址 8 sk.listen(5) #监听 9 print('waiting...') 10 conn,addr = sk.accept() #等待客户端连接 11 12 while True: 13 #防止客户端异常关闭,导致服务器端程序出错 14 try: 15 data = conn.recv(1024) 16 except Exception: 17 data = None 18 #当客户端传送的数据为空时,关闭服务器端与客户端之间的连接,等待其他客户端连接 19 if not data: 20 conn.close() 21 conn,addr = sk.accept() 22 continue 23 print(str(data, 'utf8')) # 因为接收的数据类型为bytes,所以转换成字符串再打印 24 inp = input('>>>') 25 conn.send(bytes(inp, 'utf8')) #传送的数据类型应为bytes 26 27 sk.close()
4.创建一个客户端
相比用socket建立服务器端而言,建立客户端程序简单多了。当然还是需要创建一个socket的实例,而后调这个socket实例的connect()方法来连接服务器端即可。这个方法原型为:
connect(address)
参数address 通常也是一个元组(由一个主机名/IP地址,端口构成),当然要连接本地计算机的话,主机可直接使用'localhost',它用于将socket连接到远程以address为地址的计算机。
用socket 建立客户端的基本流程:
代码实现:
1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 import socket 4 5 sk = socket.socket() #创建套接字 6 address = ('127.0.0.1', 8001) 7 sk.connect(address) # 与服务器端连接 8 while True: 9 inp = input('>>>') 10 if inp == 'exit': 11 break 12 sk.send(bytes(inp, 'utf8')) 13 data = sk.recv(1024) 14 print(str(data, 'utf8')) 15 16 sk.close()