实验目的:
 
          通过 Socket  
  编程实现  
  pyWiFi-ESP32-S3  
  与电脑服务器助手建立连接,相互收  
 
 
  
  发数据。 
 
 
  
 首先先来简单了解一下Socket
我们先来看看网络层级模型图,这是构成网络通信的基础:

 
          我们看看 TCP/IP  
  模型的传输层和应用层,传输层比较熟悉的概念是  
  TCP  
  和 UDP, 
  UPD  
  协议基本就没有对  
  IP  
  层的数据进行任何的处理了。而  
  TCP  
  协议还加入 了更加复杂的传输控制,比如滑动的数据发送窗口(Slice Window 
  ),以及接收确 认和重发机制,以达到数据的可靠传送。应用层中网页常用的则是 HTTP 
  。那么我们先来解析一下这 TCP  
  和  
  HTTP  
  两者的关系。  
 
 
  
  
          我们知道网络通信是最基础是依赖于 IP  
  和端口的, 
  HTTP  
  一般情况下默认使用端口 80。举个简单的例子:我们逛淘宝,浏览器会向淘宝网的网址(本质是IP)和端口发起请求,而淘宝网收到请求后响应,向我们手机返回相关网页数据信息,实现了网页交互的过程。而这里就会引出一个多人连接的问题,很多人访问淘宝网,实际上接收到网页信息后就断开连接,否则淘宝网的服务器是无法支撑这么多人长时间的连接的,哪怕能支持,也非常占资源。 
 
 
  
  
          也就是应用层的  
  HTTP  
  通过传输层进行数据通信时, 
  TCP  
  会遇到同时为多个应用程序进程提供并发服务的问题。多个 TCP  
  连接或多个应用程序进程可能需要通过同一个 TCP  
  协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与 TCP 
  / 
  IP  
  协议交互提供了套接字 
  (Socket)接口。应用层可以和传输层通过 Socket 接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。 
 
 
  
  
          简单来说,Socket  
  抽象层介于传输层和应用层之间, 
  跟  
  TCP/IP  
  并没有必然的联系。Socket  
  编程接口在设计的时候,就希望也能适应其他的网络协议。  
 
 
  
 
 
          套接字(socket)是通信的基石,是支持 TCP/IP 协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息: 
   
  
 
  
  
           连接使用的协议(通常是 TCP  
   或  
   UDP 
   ),本地主机的  
   IP  
   地址,本地进程的协议端  
  
 
   
   口,远地主机的  
   IP  
   地址,远地进程的协议端口。 
  
 
  
          所以,socket  
  的出现只是可以更方便的使用  
  TCP/IP  
  协议栈而已,简单理解就是其对 TCP/IP  
  进行了抽象,形成了几个最基本的函数接口。比如  
  create 
  , 
  listen, 
  accept, 
  connect 
  , 
  read  
  和  
  write  
  等等。以下是通讯流程: 
 
 
  
 
重点
 
  从上图可以看到,建了  
  Socket  
  通信需要一个服务器端和一个客户端,以本实验为例,pyWiFi-ESP32-S3  
  作为客户端,电脑使用网络调试助手作为服务器端,双方使用 TCP  
  协议传输。 
 
 
  
  
  对于客户端,则需要知道电脑端的  
  IP  
  和端口即可建立连接。(端口可以自定义,范0~65535 
  ,注意不占用常用的  
  80  
  等端口即可。)  
 
 
  
  
  以上的内容,简单来说就是如果用户面向应用来说,那么  
  ESP32-S3  
  只需要知道通讯协议是  
  TCP  
  或  
  UDP 
  、服务器的  
  IP  
  和端口号 
  这  
  3  
  个信息,即可向服务器发起连接和发送信息。就这么简单。 
 
 
  
 代码如下
'''
实验名称:Socket通讯
版本:v1.0
日期:2024.4
作者:冰美式
说明:通过Socket编程实现pyWiFi-ESP32-S3与电脑服务器助手建立TCP连接,相互收发数据
可以控制舵机。
'''
#导入相关模块
import network,usocket,time
from machine import SoftI2C,Pin,Timer, PWM
from ssd1306 import SSD1306_I2C
#初始化相关模块
i2c = SoftI2C(sda=Pin(42), scl=Pin(40))
S1 = PWM(Pin(4), freq=50, duty=0) # Servo1的引脚是0
def Servo(servo,angle):
    S1.duty(int(((angle+90)*2/180+0.5)/20*1023))
    
#WIFI连接函数
def WIFI_Connect():
    WIFI_LED=Pin(46, Pin.OUT) #初始化WIFI指示灯
    wlan = network.WLAN(network.STA_IF) #STA模式
    wlan.active(True)                   #激活接口
    start_time=time.time()              #记录时间做超时判断
    if not wlan.isconnected():
        print('Connecting to network...')
        wlan.connect('FM-674614', '12345678') #输入WIFI账号密码
        while not wlan.isconnected():
            #LED闪烁提示
            WIFI_LED.value(1)
            time.sleep_ms(300)
            WIFI_LED.value(0)
            time.sleep_ms(300)
            #超时判断,15秒没连接成功判定为超时
            if time.time()-start_time > 15 :
                print('WIFI Connected Timeout!')
                break
    if wlan.isconnected():
        #LED点亮
        WIFI_LED.value(1)
        #串口打印信息
        print('network information:', wlan.ifconfig())
        return True
    else:
        return False
#判断WIFI是否连接成功
if WIFI_Connect():
    #创建socket连接TCP类似,连接成功后发送“Hello 01Studio!”给服务器。
    s=usocket.socket()
    addr=('192.168.0.101',10000) #服务器IP和端口
    s.connect(addr)
    s.send('Hello 01Studio!')
while True:
    data = s.recv(128)  # 单次最多接收 128 字节
    if data == b'':
        pass
    else:  # 打印接收到的信息为字节,可以通过 decode('utf-8')转成字符串
        print(data)
        number = int(data.decode('utf-8'))  # 将接收到的字节数据转换为整数
        s.send(b'I got: ' + data)  # 发送确认收到的信息给服务器
        Servo(S1, number)  # 调用 Servo() 函数并传递整数值
    time.sleep_ms(300)
 
 注意,要改成相同的路由WIFI密码,服务器的IP是本机电脑的IP(用ipconfig可以查到)。然后端口写 10000(0-65535 都可以)。
 
  WIFI  
  连接成功后返回  
  True 
  ,否则返回 False 
  。程序在返回连接成功后建了  
  Socket  
  连接,连接成功发送‘ 
  Hello 01Studio!’信息到服务器。另外  
  RTOS  
  定时器设定了了每  
  300ms  
  处理从服务器接  
 
 
  
  收到的数据。将接收到数据通过串口打印和发送给服务器。 
 
 
  
 
中间的IP地址是电脑本机的IP地址,端口号注意与thonny里面绑定给ESP32的端口号要一致。

成功如下:

 
  选中后我们在发送框输入信息“ 
  Hi 
  ”,点击发送,可以看到开发板的  
  REPL  
  打 
  235  
 
 
  
  印出来信息  
  Hi 
  。为字节数据。另外由于程序将收到的信息发回给服务器,所以在  
 
 
  
  网络调试助手中也接收到开发板返回的信息: 
  I got:Hi 
  。 
 
 
  
 
你发送数字,舵机可以转动。


















