24.Python 网络编程:socket编程

1.认识TCP/IP

计算机网络就是把各个计算机连接在一起,在网络中的计算机可以互相通信。

网络编程是如何在程序中实现两台计算机的通信。

网络通信是两台计算机上的两个进程之间的通信。

为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,互联网协议包含了上百种,但最重要的有TCP和IP协议。

TCP/IP 协议被分为4层:应用层、传输层、网络层、接口层:

  • 应用层协议有HTTP、FTP、SMTP等,用来接收来自传输层的数据或按不同应用要求及方式将数据传输至传输层。
  • 传输层协议有UDP、TCP,实现数据传输与数据共享。
  • 网络层协议有ICMP、IP、IGMP,主要负责网络中的数据包的传送等。
  • 接口层协议有ARP、RARP,主要提供链路管理、错误检测、对不同通信媒介有关信息细节问题进行有效处理等。

通信双方必须知道对方的标识,互联网每个计算 机的唯一标识就是IP地址。如果一台计算机同时接入两个或更多的网络,如路由器,就要有两个或多个IP地址。所以,IP地址对应的实际上是计算机的网络接口,通常是网卡。

TCP协议是建立IP协议之上的,负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。

2.socket编程

socket 是应用层与传输层、网络层之间进行通信的中间软件抽象层,是一组接口,把复杂的TCP/IP协议隐藏在socket接口后面,对用户来说,一组简单的接口就是全部,调用socket接口函数去组织数据,以符合指定的协议,这样网络间的通信业就简单了许多。

Python 提供了两个基本的socket处理模块。

  • socket:提供了标准的BSD Sockets API,可以访问底层操作系统socket接口的全部方法。
  • socketsever:提供了服务器中心类,可以简化网络服务器的开发。

2.1 使用socket

服务器

服务器端进程需要申请套接字,然后绑定套接字进行监听。当有客户端发送请求,则接收数据并进行处理,处理完后对客户端进行响应。

  1. 创建套接字
import socket
# socket模块的socket()函数能创建socket对象
socket.socket([family[,type[,proto]]])
'''
family:设置套接字种族,包括AF_UNIX和AF_INET,常用AF_INET选项。
type:设置套接字类型。
proto:协议类型,默认为0,一般不填。
'''
s1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 网络通信,协议类型
  1. 绑定套接字
s1.bind(address) # address 地址必须是一个元组:(host,port)
s1.bind((host,port))
  1. 监听套接字
s1.listen(backlog) # backlog指定最多允许多少个客户端连接服务器
  1. 等待接受连接
connection,address = s1.accept() # 阻塞状态
  1. 处理阶段
# 数据以字节串格式返回,bufsize指定最多可以接受的数量。
connection.recv(bufsize[,flag]) 
# 发送给连接的客户端套接字
connection.send(string[,flag])
  1. 关闭连接
s1.close()

客户端

客户端只需要申请一个套接字,然后通过套接字连接到服务器端,建立连接之后就可以通信。

  1. 创建套接字socket对象。
import socket # 导入socket模块
s2 = socket.socket()  # 实例化socket 对象
  1. 连接到服务器端。
s2.connect(address) # address 地址必须是一个元组:(host,port)
  1. 处理阶段。
# 数据以字节串格式返回,bufsize指定最多可以接受的数量。
s2.recv(bufsize[,flag])  
# 将参数string包含的字节串发送到服务器端
s2.send(string[,flag]) 
  1. 关闭连接。
s2.close()

示例:使用socket模块构建一个网络通信服务。

# 新建server.py,输入以下命令,作为服务器端响应文件
import socket
# 创建服务端服务
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('localhost',6999)) # 绑定要监听的端口,本地计算机6999
s.listen(5) # 开始监听,使用5个连接排队
while True:
    conn,addr = s.accept()
    print(conn,addr) # 输出连接信息
    try:
        data = conn.recv(1024) # 接收数据
        print('recive:',data.decode()) # 解码
        conn.send(data.upper()) # 发送数据
        conn.close() # 关闭连接
    except:
        print('出现异常')
        break
# 新建client.py,输入以下命令,作为客户端请求文件
import socket
c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
c.connect(('localhost',6999)) #
msg = '欢迎新同学!'
c.send(msg.encode('utf-8')) # 发送一条信息,将字符串转换为字节流
data = c.recv(1024) # 接收信息,大小为1024字节
print('recv:',data.decode()) # 输出接收信息
c.close() # 关闭

在这里插入图片描述

2.2 使用socketserver

socketserver模块封装了socket模块和select模块,使用多线程处理多个客户端的连接,使用select模块处理高并发访问。

  • 服务类:提供了建立连接的过程,如绑定、监听、运行等。
  • 请求处理类:专注于如何处理用户发送的数据

服务类

服务类包含5种类型:

  • BaseServer:不直接对外服务。
  • TCPServer:针对TCP套接字流。
  • UDPServer:针对UDP数据报套接字。
  • UnixStreamServer和UnixDatagramServer:针对Unix域套接字,不常用。

请求处理类

socketserver 模块提供请求处理类BaseRequestHandler, 以及派生类StreamRequestHandler(处理流式套接字)和DatagramRequestHandler(处理数据报套接字)。请求处理类有3种方法:

  • setup():在handle()之前被调用,执行处理请求前的初始化操作,默认不做任何事情。
  • handle():执行与处理请求相关的工作。
  • finish():在handle()之后调用,执行处理完请求后的清理操作,默认不做任何事情。

使用socketserver创建一个服务,具体步骤如下:

  1. 创建一个请求处理类,选择StreamRequestHandler或DatagramRequestHandler作为父类,也可以选择BaseRequestHandler作为父类,并重写handle()方法。
  2. 实例化一个服务类对象,并将服务的地址和第1步创建的请求处理类传递给它。
  3. 调用服务类对象的handle_request()或server_forever()方法开始处理请求。

示例:使用socketserver模块构建一个网络通信服务。

# 新建server1.py,输入以下命令,作为服务器端响应文件
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler): # 自定义请求处理类
    def handle(self): # 重写handle()方法
        try:
            while True:
                self.data = self.request.recv(1024) # 接收数据
                print(self.client_address,self.data)  # 打印数据
                if not self.data: # 如果没有接收到数据
                    print('连接丢失')
                    break # 结束轮询
                self.request.sendall(self.data.upper()) # 向客户端响应数据
        except Exception as e:
            print(self.client_address,'连接断开')
        finally:
            self.request.close() # 关闭
    def setup(selfself): # 重写setup()方法
        print('setup被执行')
    def finish(self): # 重写finish()方法
        print('finish被执行')
if __name__ == "__main__":
    s = socketserver.TCPServer(('localhost',9999),MyTCPHandler)
    s.serve_forever()
# 新建client1.py,输入以下命令,作为客户端请求文件
import socket
c = socket.socket()
c.connect(('localhost',9999)) # 连接到服务器
while True:
    cmd = input('是否退出(y/n)').strip() # 是否退出
    if len(cmd)==0:
        continue
    if cmd=='y' or cmd=='Y': # 退出交流
        break
    c.send(cmd.encode()) # 发送信息
    cmd_res=c.recv(1024) # 接收信息
    print(cmd_res.decode()) # 打印信息
c.close() # 关闭

在这里插入图片描述

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,关于Python Socket服务器,以下是一些基本的学习笔记: 1. 创建Socket服务器 使用Python中的`socket`模块创建Socket服务器,可以使用`socket()`函数来创建一个Socket对象,如下所示: ```python import socket # 创建一个Socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ``` 其中,第一个参数`AF_INET`表示使用IPv4地址族,第二个参数`SOCK_STREAM`表示使用TCP协议,如果使用UDP协议,则应该使用`SOCK_DGRAM`。 2. 绑定Socket服务器 在创建Socket对象之后,需要使用`bind()`方法将Socket对象和一个IP地址及端口号绑定在一起,如下所示: ```python # 绑定IP地址和端口号 server_socket.bind(('127.0.0.1', 8888)) ``` 其中,`bind()`方法的参数是一个元组,第一个元素是IP地址,第二个元素是端口号。 3. 监听Socket服务器 在绑定IP地址和端口号之后,需要使用`listen()`方法开始监听Socket服务器,如下所示: ```python # 开始监听 server_socket.listen(5) ``` 其中,`listen()`方法的参数表示最大连接数,即同时可以连接的客户端数量。 4. 接受客户端连接 当有客户端连接到Socket服务器时,需要使用`accept()`方法来接受客户端连接,如下所示: ```python # 接受客户端连接 client_socket, client_address = server_socket.accept() ``` 其中,`accept()`方法返回一个元组,第一个元素是客户端的Socket对象,第二个元素是客户端的IP地址和端口号。 5. 接收和发送数据 客户端连接到Socket服务器之后,就可以进行数据的接收和发送了,使用`recv()`方法接收客户端发送的数据,使用`send()`方法向客户端发送数据,如下所示: ```python # 接收客户端数据 data = client_socket.recv(1024) # 发送服务器数据 client_socket.send(b'Hello, client!') ``` 其中,`recv()`方法的参数表示接收数据的最大字节数,`send()`方法的参数是要发送的数据,需要将其转换为字节串。 6. 关闭Socket服务器 当与客户端的通信完成后,需要使用`close()`方法关闭Socket服务器,如下所示: ```python # 关闭Socket服务器 server_socket.close() ``` 以上是关于Python Socket服务器的一些基本学习笔记,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有请小发菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值