Python网络编程之socket模块

时间:2022-02-06 23:56:08

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就要依次使用这几个方法,其基本顺序为:

 Python网络编程之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 建立客户端的基本流程:

  Python网络编程之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()