python套接字socket编程,原理、步骤、计算器实例

什么是套接字socket编程

套接字socket是一种客户端/服务器端,即C/S的架构机制,主要用于网络中的进程之间的通信。需要两个特殊的文件,一个在服务器端,一个在客户端,并各自维护。

套接字socket编程更重要的是其编程思想,而且每一种计算机语言(可以用来写后端的语言)基本上都可以实现套接字socket编程,而不是python的专有的。

socket(网络)编程实际上就是对文件进行打开、关闭、读/写的操作,之前在网络编程那一章节介绍过网络编程到底编了个啥,里头有介绍说了网络编程更多的是在应用层开发,处理数据包的组装、发送、接收、解码、呈现等通信任务,这其中的数据包便可理解为文件。


python语言socket编程服务器端的原理机制、步骤

如上所言,socket编程的过程实际上就是对文件进行“打开、关闭、读/写”的操作,下面,我们就基于这三个步骤来堆socket编程的原理机制进行进一步的细化。

步骤:服务器端接收文件

服务器端打开文件之前,需要接收文件,于是就有了下面的方法、步骤:

  1. 创建socket对象:用socket()函数;
  2. 绑定IP地址和端口:用bind()函数;
  3. 监听端口,等待客户端发送来的请求:用listen()函数;
  4. 阻塞客户端的请求:用accept()函数,参考:阻塞和非阻塞
  5. 接收数据:用recv()函数

步骤:服务器端读/写数据

服务器端通过socket套接字接收数据之后,就是相应的数据处理,或者说是数据交互,这个过程中可以根据自个的需求来设计程序。


步骤:服务器端发送数据

数据处理完成之后,需要通过发送处理完的数据给客户端,以完成C/S架构的数据交互,该过程中使用send()或sendall()函数。


步骤:服务器端关闭连接

客户端的请求处理完成之后,服务器端的socket需要关闭连接,好腾出线程时间片。这个过程中close()函数。


客户端socket编程的原理机制、步骤

客户端的socket编程基本类似,不过相对来说会简单许多:

步骤:客户端创建socket对象

也是用socket()函数;


步骤:客户端通过IP/端口链接服务器端

用connect( address )向服务器端发起连接,其中address以元组的形式传参,如果发生错误,会引发socket.error错误。


步骤:客户端发送数据

用send()或sendall()函数


步骤:客户端接收数据

用recv()函数


步骤:客户端关闭连接

用close()函数

socket编程实例

下面我们用python的socket编程开发一个客户端和服务器端交互而成的计算器。注意,这里的客户端和服务器端都在本地(本机)。

server.py服务器端

# -*- coding:utf-8 -*-
import socket

ip_port = ('127.0.0.1',5656) 
#记住address是元组的格式,其中127.0.0.1通常用来表示本机,5656表示端口;
# 通常情况下,0~1023是保留端口,1024~65535为用户端口,可以随便设置。

#步骤:用socket()方法创建socket对象
sk = socket.socket()

#步骤:用bind()方法绑定服务器地址,这里是本机
sk.bind(ip_port)

#步骤:用listen()函数监听客户端发送来的请求
sk.listen(5)
#其中5表示在拒绝连接之前,操作系统可以挂起的最大连接数量

#步骤:利用阻塞机制,等待连接
connect, address = sk.accept()
#accept()函数返回的connect是连接的通信对象,用来接收、发送数据,address是连接客户端的地址

while True:
    data = connect.recv(1024).decode()
    #1024为一次接收数据的最大量——数据可以分多次进行接收——这样可以避免数据太大,瘫痪内存;
    #网络编程就是对数据按规定好的协议进行组装成包、发送、接收、解码、呈现等过程的处理,
    #所以注意decode()函数解码的作用
    if data == 'socket_ok': 
        print('通信完成')
        break
    datalist = list(data)
    f = datalist[1]
    a = float(datalist[0])
    b = float(datalist[2])
    if f == '+':
        result = a+b
    elif f == '-':
        result = a-b
    elif f == '*':
        result = a*b
    elif f== '/':
        result = a/b
    else:
        continue
    connect.sendall(str(result).encode()) #这里为什么要用str()函数来转化呢?因为int或float类型没有encode()函数
    #有解码,就必须有编码encode()就是用来编码的

connect.close()

client.py客户端

# -*- coding:utf-8 -*-
import socket

ip_port = ('127.0.0.1', 5656) 
#注意要与server端的保持一致

#创建socket对象
sk = socket.socket()

#连接server端
sk.connect(ip_port)

while True:
    data = input('计算:')
    if data == '':
        continue
    data = data.encode() #发送之前要进行编码
    sk.sendall(data)
    if data == 'socket_ok':
        print("socket结束!")
    recv_data = sk.recv(1024).decode()
    if recv_data != '':
        print('%s = %s'%(data,recv_data))
sk.close()

如何同时运行python两个脚本文件

因为这是服务器端和客户端的通信,所以必须两个都是启动运行的状态。我们可以用如下代码在终端同时运行两个python脚本文件:

python3 server.py & python3 client.py

需要注意两点:1、为什么是python3而不是python,这是为了避免python版本的冲突导致程序出错;2、server.py服务器端的脚本文件应该先运行。

上面实例的代码输出:
算:1+2
b'1+2' = 3.0
计算:1/2
b'1/2' = 0.5
计算:1*2
b'1*2' = 2.0

socket编程出现 [Errno 61] Connection refused错误怎么办

因为服务器端和客户端都在本地(本机上),所以很可能会发生 [Errno 61] Connection refused错误,那该怎么办呢?可以参考:socket编程出现 [Errno 61] Connection refused错误解决办法

python的socket编程的原理、步骤就先介绍到这里,下一节我们将介绍socket的多线程服务器。


全栈后端 / python教程 :


























Copyright © 2022-2024 笨鸟工具 x1y1z1.com All Rights Reserved.