易语言网络通信编程基础:HTTP/HTTPS/TCP/UDP实战开发

易语言网络通信编程基础:HTTP/HTTPS/TCP/UDP实战开发

5.1 引言

💡 在完成了本地数据持久化的学习后,网络通信编程是易语言应用开发的又一个核心技能点。现代软件几乎都离不开网络交互:从获取实时天气、新闻资讯的简单API调用,到开发在线聊天工具、文件传输系统的复杂通信,再到爬虫、数据采集的自动化任务,网络通信都是实现这些功能的基础。

易语言提供了丰富的网络通信组件和命令,如internet支持库 用于HTTP/HTTPS通信,网络通信支持库 用于TCP/UDP通信,WebSocket支持库用于实时双向通信。这些组件和命令屏蔽了网络底层的复杂细节,让中文开发者能够快速上手。

5.1.1 学习目标

  • 了解网络通信的基础概念(IP地址、端口、协议、客户端/服务器模型)
  • 掌握HTTP/HTTPS通信的常用方法(GET/POST请求、响应解析)
  • 学会使用TCP通信组件开发可靠的客户端和服务器端应用
  • 学会使用UDP通信组件开发高效的无连接应用
  • 综合运用所学知识,完成三个实战案例:
    • 调用天气API获取实时天气
    • 开发一个简单的TCP聊天工具(服务端+客户端)
    • 开发一个简单的UDP广播工具
  • 掌握网络通信的常见问题及解决方案(网络连接失败、请求超时、数据解析错误等)

5.1.2 学习重点

  • HTTP请求的参数构建和响应解析(特别是JSON数据解析)
  • TCP通信的连接建立、数据收发和异常处理
  • UDP通信的数据包发送和接收
  • 网络通信的超时设置和重试机制
  • 天气API的调用和JSON解析库的使用
  • TCP聊天工具的UI设计和多客户端通信处理

5.2 网络通信基础概念

在进行网络通信编程之前,我们需要了解一些基础概念。

5.2.1 IP地址

IP地址是设备在网络中的唯一标识,类似于家庭住址。常用的IP地址有两种类型:

  • IPv4:32位二进制数,通常用点分十进制表示(如192.168.1.1)
  • IPv6:128位二进制数,通常用冒分十六进制表示(如2001:0db8:85a3:0000:0000:8a2e:0370:7334)

💡 易语言支持IPv4和IPv6地址,但目前IPv4仍占主导地位。

5.2.2 端口

端口是设备上进程的唯一标识,类似于家庭住址中的房间号。每个网络进程都会占用一个端口,范围是0~65535。其中:

  • 0~1023:系统预留端口(如HTTP的80端口、HTTPS的443端口、FTP的21端口)
  • 1024~49151:注册端口(由ICANN分配给特定服务)
  • 49152~65535:动态端口(临时分配给客户端进程)

5.2.3 网络协议

网络协议是设备之间通信的规则和标准,常用的网络协议有:

协议 类型 特点 适用场景
TCP 传输层 可靠、面向连接、三次握手 文件传输、聊天工具、邮件发送
UDP 传输层 不可靠、无连接、速度快 视频通话、音频直播、游戏数据传输
HTTP 应用层 基于TCP的文本协议、无状态 网页访问、API调用
HTTPS 应用层 基于HTTP的加密协议、安全 支付、登录等需要安全保障的场景

5.2.4 客户端/服务器模型

网络通信通常采用客户端/服务器(C/S)模型

  • 客户端:主动发起连接请求的设备(如浏览器、聊天工具客户端)
  • 服务器:被动接受连接请求的设备(如Web服务器、聊天工具服务器)

5.3 HTTP/HTTPS通信

HTTP/HTTPS通信是最常用的网络通信方式,用于获取网页内容和调用API。

5.3.1 internet支持库介绍

易语言的internet支持库提供了HTTP/HTTPS通信的常用命令和组件,需要在支持库管理器中勾选才能使用。

常用命令:

  • HTTP读文件():发送HTTP GET请求,获取响应内容
  • HTTP访问():发送HTTP请求(GET/POST/HEAD等),获取响应状态码和内容
  • HTTP提交():发送HTTP POST请求,提交表单数据
  • HTTP下载():下载文件到本地
  • HTTP上传():上传本地文件到服务器

5.3.2 HTTP GET请求实战:调用天气API

天气API介绍

我们将使用和风天气APIhttps://idqweather.com/)获取实时天气数据。和风天气提供免费的API,每天有600次调用次数限制,适合学习使用。

代码示例
e 复制代码
.版本 2
.支持库 internet
.支持库 spec
.支持库 json ' 需要加载json支持库

' 和风天气API密钥(需要在和风天气官网注册获取)
.程序集变量 g_ApiKey, 文本型, , 静态
' 城市编码(如北京:101010100)
.程序集变量 g_CityCode, 文本型, , 静态

.子程序 __启动窗口_创建完毕
' 初始化组件属性
_启动窗口.标题 = "实时天气查询工具"
_启动窗口.宽度 = 600
_启动窗口.高度 = 400
_启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2
_启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2

' 初始化API密钥和城市编码
g_ApiKey = "your_api_key_here" ' 替换为你的API密钥
g_CityCode = "101010100" ' 北京的城市编码

' 加载默认天气数据
加载天气数据 ()

.子程序 加载天气数据
.局部变量 请求URL, 文本型
.局部变量 响应内容, 文本型
.局部变量 JSON对象, 类_json
.局部变量 实时天气对象, 类_json
.局部变量 天气描述, 文本型
.局部变量 温度, 文本型
.局部变量 湿度, 文本型
.局部变量 风向, 文本型
.局部变量 风速, 文本型
.局部变量 气压, 文本型

' 构建请求URL
请求URL = "https://devapi.qweather.com/v7/weather/now?location=" + g_CityCode + "&key=" + g_ApiKey

' 发送HTTP GET请求
响应内容 = HTTP读文件 (请求URL)
.如果真 (响应内容 = "")
    信息框 ("天气数据获取失败!请检查网络连接或API密钥是否正确。", 0, "错误提示")
    返回 ()
.如果真结束

' 解析响应内容(JSON格式)
JSON对象.解析 (响应内容)
.如果真 (JSON对象.取通用属性 ("code", ).文本型 ≠ "200")
    信息框 ("天气数据获取失败!错误信息:" + JSON对象.取通用属性 ("message", ).文本型, 0, "错误提示")
    返回 ()
.如果真结束

' 解析实时天气数据
实时天气对象 = JSON对象.取通用属性 ("now", )
天气描述 = 实时天气对象.取通用属性 ("text", ).文本型
温度 = 实时天气对象.取通用属性 ("temp", ).文本型 + "℃"
湿度 = 实时天气对象.取通用属性 ("humidity", ).文本型 + "%"
风向 = 实时天气对象.取通用属性 ("windDir", ).文本型
风速 = 实时天气对象.取通用属性 ("windSpeed", ).文本型 + "km/h"
气压 = 实时天气对象.取通用属性 ("pressure", ).文本型 + "hPa"

' 显示天气数据
lblWeather.标题 = "天气:" + 天气描述
lblTemperature.标题 = "温度:" + 温度
lblHumidity.标题 = "湿度:" + 湿度
lblWind.标题 = "风向:" + 风向 + ",风速:" + 风速
lblPressure.标题 = "气压:" + 气压

调试输出 ("天气数据获取成功!响应内容:", 响应内容)

.子程序 _btnRefresh_被单击
' 刷新天气数据
加载天气数据 ()

.子程序 _cboCity_项目被选择
.局部变量 城市编码数组, 文本型, 数组
.局部变量 选中索引, 整数型

' 城市编码数组(城市名称|城市编码)
城市编码数组 = {"北京|101010100", "上海|101020100", "广州|101280101", "深圳|101280601", "杭州|101210101", "南京|101190101", "成都|101270101", "武汉|101200101"}

' 获取选中索引
选中索引 = cboCity.现行选中项
' 获取城市编码
g_CityCode = 取文本右边 (城市编码数组 [选中索引], 取文本长度 (城市编码数组 [选中索引]) - 取文本长度 (取文本左边 (城市编码数组 [选中索引], 寻找文本 (城市编码数组 [选中索引], "|", 1, 真) - 1)) - 1)

' 刷新天气数据
加载天气数据 ()
调试与运行
  1. 在和风天气官网注册账号,获取API密钥
  2. 替换代码中的your_api_key_here为你的API密钥
  3. 点击"调试"按钮进入调试模式
  4. 选择不同的城市,查看实时天气数据

5.3.3 HTTP POST请求实战:提交表单数据

HTTP POST请求通常用于提交表单数据或上传文件,我们将开发一个简单的"用户注册"模拟工具。

代码示例
e 复制代码
.版本 2
.支持库 internet
.支持库 spec
.支持库 json

' 模拟服务器地址
.程序集变量 g_ServerUrl, 文本型, , 静态

.子程序 __启动窗口_创建完毕
' 初始化组件属性
_启动窗口.标题 = "用户注册模拟工具"
_启动窗口.宽度 = 500
_启动窗口.高度 = 350
_启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2
_启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2

' 初始化模拟服务器地址(可以使用httpbin.org模拟HTTP请求)
g_ServerUrl = "https://httpbin.org/post"

.子程序 _btnRegister_被单击
.局部变量 表单数据, 文本型
.局部变量 响应内容, 文本型
.局部变量 JSON对象, 类_json
.局部变量 请求结果, 文本型
.局部变量 请求时间, 文本型

' 检查输入是否为空
.如果真 (txtUsername.内容 = "" 或 txtPassword.内容 = "" 或 txtEmail.内容 = "")
    信息框 ("请输入用户名、密码和邮箱!", 0, "错误提示")
    返回 ()
.如果真结束

' 构建表单数据(JSON格式)
表单数据 = "{" + #引号 + "username" + #引号 + ":" + #引号 + txtUsername.内容 + #引号 + "," + #引号 + "password" + #引号 + ":" + #引号 + txtPassword.内容 + #引号 + "," + #引号 + "email" + #引号 + ":" + #引号 + txtEmail.内容 + #引号 + "}"

' 发送HTTP POST请求
响应内容 = HTTP访问 (g_ServerUrl, "POST", "Content-Type: application/json" + #换行符 + "", 到字节集 (表单数据))
.如果真 (响应内容 = "")
    信息框 ("用户注册失败!请检查网络连接。", 0, "错误提示")
    返回 ()
.如果真结束

' 解析响应内容(JSON格式)
JSON对象.解析 (响应内容)
请求结果 = JSON对象.取通用属性 ("status", ).文本型
.如果真 (请求结果 ≠ "200")
    信息框 ("用户注册失败!错误信息:" + JSON对象.取通用属性 ("message", ).文本型, 0, "错误提示")
    返回 ()
.如果真结束

' 显示请求结果
lblResult.标题 = "注册成功!"
lblResult.字体.颜色 = #绿色
请求时间 = JSON对象.取通用属性 ("json", ).取通用属性 ("time", ).文本型
.如果真 (请求时间 = "")
    请求时间 = 到文本 (取现行时间 (), , "yyyy年MM月dd日 HH时mm分ss秒")
.如果真结束

调试输出 ("用户注册成功!响应内容:", 响应内容)
调试与运行
  1. 点击"调试"按钮进入调试模式
  2. 输入用户名、密码和邮箱,点击"注册"
  3. 查看响应结果

5.4 TCP通信

TCP通信是一种可靠的面向连接的通信方式,适合开发需要稳定传输的应用,如聊天工具、文件传输系统。

5.4.1 网络通信支持库介绍

易语言的网络通信支持库提供了TCP和UDP通信的组件,需要在支持库管理器中勾选才能使用。

常用组件:

  • 客户组件:用于开发TCP客户端应用
  • 服务端组件:用于开发TCP服务器端应用
  • UDP组件:用于开发UDP客户端和服务器端应用

5.4.2 TCP聊天工具实战(服务端)

设计思路
  • 使用服务端组件监听指定端口
  • 接受客户端的连接请求
  • 处理客户端的消息,并转发给其他客户端
  • 显示客户端的连接和断开信息
创建工程与添加组件
  1. 创建一个新的Windows窗口程序工程
  2. 加载必要的支持库:系统核心支持库网络通信支持库
  3. 添加以下组件:
    • 标签组件:2个,分别用于显示"监听端口"和"聊天记录"
    • 文本框组件:1个,用于输入监听端口
    • 编辑框组件:1个,用于显示聊天记录
    • 按钮组件:2个,分别用于"启动监听"和"停止监听"
    • 服务端组件:1个,用于监听和接受连接
设置组件属性
组件名称 属性名 属性值
标签1 标题 监听端口
标签1 名称 lblPort
标签2 标题 聊天记录
标签2 名称 lblChatRecord
文本框1 名称 txtPort
文本框1 内容 8888
编辑框1 名称 edtChatRecord
编辑框1 是否允许多行 #真
编辑框1 滚动条 #垂直滚动条
按钮1 名称 btnStartListen
按钮1 标题 启动监听
按钮2 名称 btnStopListen
按钮2 标题 停止监听
按钮2 禁止 #真
服务端组件1 名称 sckServer
编写代码
e 复制代码
.版本 2
.支持库 spec
.支持库 internet
.支持库 eNetCom

' 已连接的客户端数组
.程序集变量 g_Clients, 文本型, 动态数组
' 聊天记录
.程序集变量 g_ChatRecord, 文本型

.子程序 __启动窗口_创建完毕
' 初始化组件属性
_启动窗口.标题 = "TCP聊天工具服务器端"
_启动窗口.宽度 = 600
_启动窗口.高度 = 500
_启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2
_启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2

' 初始化聊天记录
g_ChatRecord = "服务器启动时间:" + 到文本 (取现行时间 (), , "yyyy年MM月dd日 HH时mm分ss秒") + #换行符

.子程序 _btnStartListen_被单击
.局部变量 监听端口, 整数型

' 检查端口是否合法
监听端口 = 到数值 (txtPort.内容)
.如果真 (监听端口 < 1024 或 监听端口 > 65535)
    信息框 ("监听端口必须在1024~65535之间!", 0, "错误提示")
    返回 ()
.如果真结束

' 启动监听
.如果真 (sckServer.启动监听 (监听端口) = #假)
    信息框 ("监听端口失败!请检查端口是否被占用。", 0, "错误提示")
    返回 ()
.如果真结束

' 禁用启动按钮,启用停止按钮
btnStartListen.禁止 = #真
btnStopListen.禁止 = #假

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "服务器已启动监听,端口:" + 到文本 (监听端口) + #换行符
edtChatRecord.内容 = g_ChatRecord

调试输出 ("服务器已启动监听,端口:", 监听端口)

.子程序 _btnStopListen_被单击
' 停止监听
sckServer.停止监听 ()

' 禁用停止按钮,启用启动按钮
btnStartListen.禁止 = #假
btnStopListen.禁止 = #真

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "服务器已停止监听!" + #换行符
edtChatRecord.内容 = g_ChatRecord

调试输出 ("服务器已停止监听!")

.子程序 _sckServer_客户端进入
.局部变量 客户端IP, 文本型
.局部变量 客户端端口, 整数型

' 获取客户端IP和端口
客户端IP = sckServer.取客户端IP (sckServer.现行客户)
客户端端口 = sckServer.取客户端端口 (sckServer.现行客户)

' 添加到已连接客户端数组
加入成员 (g_Clients, 客户端IP + ":" + 到文本 (客户端端口))

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "【系统消息】客户端 " + 客户端IP + ":" + 到文本 (客户端端口) + " 已连接!" + #换行符
edtChatRecord.内容 = g_ChatRecord

' 向所有已连接客户端广播系统消息
广播系统消息 ("【系统消息】客户端 " + 客户端IP + ":" + 到文本 (客户端端口) + " 已连接!")

调试输出 ("客户端 " + 客户端IP + ":" + 到文本 (客户端端口) + " 已连接!")

.子程序 _sckServer_客户端离开
.局部变量 客户端IP, 文本型
.局部变量 客户端端口, 整数型

' 获取客户端IP和端口
客户端IP = sckServer.取客户端IP (sckServer.现行客户)
客户端端口 = sckServer.取客户端端口 (sckServer.现行客户)

' 从已连接客户端数组中删除
删除成员 (g_Clients, 查找数组索引 (g_Clients, 客户端IP + ":" + 到文本 (客户端端口)) + 1, 1)

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "【系统消息】客户端 " + 客户端IP + ":" + 到文本 (客户端端口) + " 已断开!" + #换行符
edtChatRecord.内容 = g_ChatRecord

' 向所有已连接客户端广播系统消息
广播系统消息 ("【系统消息】客户端 " + 客户端IP + ":" + 到文本 (客户端端口) + " 已断开!")

调试输出 ("客户端 " + 客户端IP + ":" + 到文本 (客户端端口) + " 已断开!")

.子程序 _sckServer_数据到达
.局部变量 客户端IP, 文本型
.局部变量 客户端端口, 整数型
.局部变量 接收数据, 字节集
.局部变量 消息内容, 文本型

' 获取客户端IP和端口
客户端IP = sckServer.取客户端IP (sckServer.现行客户)
客户端端口 = sckServer.取客户端端口 (sckServer.现行客户)

' 接收数据
接收数据 = sckServer.接收数据 (sckServer.现行客户)
消息内容 = 到文本 (接收数据, #UTF_8, )

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "【" + 客户端IP + ":" + 到文本 (客户端端口) + "】" + 消息内容 + #换行符
edtChatRecord.内容 = g_ChatRecord

' 向所有已连接客户端广播消息
广播消息 ("【" + 客户端IP + ":" + 到文本 (客户端端口) + "】" + 消息内容)

调试输出 ("客户端 " + 客户端IP + ":" + 到文本 (客户端端口) + " 发送消息:" + 消息内容)

.子程序 查找数组索引, 整数型
.参数 数组, 文本型, 数组
.参数 查找内容, 文本型
.局部变量 i, 整数型

.计次循环首 (取数组成员数 (数组), i)
    .如果真 (数组 [i - 1] = 查找内容)
        返回 (i - 1)
    .如果真结束
.计次循环尾 ()

返回 (-1)

.子程序 广播消息
.参数 消息内容, 文本型
.局部变量 i, 整数型

' 向所有已连接客户端广播消息
.计次循环首 (取数组成员数 (g_Clients), i)
    ' 发送消息
    sckServer.发送数据 (i, 到字节集 (消息内容, #UTF_8, ))
.计次循环尾 ()

.子程序 广播系统消息
.参数 消息内容, 文本型
.局部变量 i, 整数型

' 向所有已连接客户端广播系统消息
.计次循环首 (取数组成员数 (g_Clients), i)
    ' 发送系统消息(使用特殊前缀标识)
    sckServer.发送数据 (i, 到字节集 ("[SYSTEM]" + 消息内容, #UTF_8, ))
.计次循环尾 ()

5.4.3 TCP聊天工具实战(客户端)

设计思路
  • 使用客户组件连接到服务器端
  • 发送消息到服务器端
  • 接收服务器端的消息,并显示在聊天记录中
  • 处理服务器端的系统消息(使用特殊前缀标识)
创建工程与添加组件
  1. 创建一个新的Windows窗口程序工程
  2. 加载必要的支持库:系统核心支持库网络通信支持库
  3. 添加以下组件:
    • 标签组件:3个,分别用于显示"服务器IP"、"服务器端口"和"聊天记录"
    • 文本框组件:3个,分别用于输入服务器IP、服务器端口和消息内容
    • 编辑框组件:1个,用于显示聊天记录
    • 按钮组件:3个,分别用于"连接服务器"、"断开连接"和"发送消息"
    • 客户组件:1个,用于连接和通信
设置组件属性
组件名称 属性名 属性值
标签1 标题 服务器IP
标签1 名称 lblServerIP
标签2 标题 服务器端口
标签2 名称 lblServerPort
标签3 标题 聊天记录
标签3 名称 lblChatRecord
文本框1 名称 txtServerIP
文本框1 内容 127.0.0.1
文本框2 名称 txtServerPort
文本框2 内容 8888
文本框3 名称 txtMessage
文本框3 内容
编辑框1 名称 edtChatRecord
编辑框1 是否允许多行 #真
编辑框1 滚动条 #垂直滚动条
按钮1 名称 btnConnect
按钮1 标题 连接服务器
按钮2 名称 btnDisconnect
按钮2 标题 断开连接
按钮2 禁止 #真
按钮3 名称 btnSendMessage
按钮3 标题 发送消息
按钮3 禁止 #真
客户组件1 名称 sckClient
编写代码
e 复制代码
.版本 2
.支持库 spec
.支持库 internet
.支持库 eNetCom

' 聊天记录
.程序集变量 g_ChatRecord, 文本型

.子程序 __启动窗口_创建完毕
' 初始化组件属性
_启动窗口.标题 = "TCP聊天工具客户端"
_启动窗口.宽度 = 550
_启动窗口.高度 = 480
_启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2
_启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2

' 初始化聊天记录
g_ChatRecord = "客户端启动时间:" + 到文本 (取现行时间 (), , "yyyy年MM月dd日 HH时mm分ss秒") + #换行符

.子程序 _btnConnect_被单击
.局部变量 服务器IP, 文本型
.局部变量 服务器端口, 整数型

' 检查服务器IP是否合法
服务器IP = txtServerIP.内容
.如果真 (服务器IP = "")
    信息框 ("请输入服务器IP!", 0, "错误提示")
    返回 ()
.如果真结束

' 检查服务器端口是否合法
服务器端口 = 到数值 (txtServerPort.内容)
.如果真 (服务器端口 < 1024 或 服务器端口 > 65535)
    信息框 ("服务器端口必须在1024~65535之间!", 0, "错误提示")
    返回 ()
.如果真结束

' 连接服务器
.如果真 (sckClient.连接 (服务器IP, 服务器端口) = #假)
    信息框 ("连接服务器失败!请检查服务器是否已启动监听,或网络连接是否正常。", 0, "错误提示")
    返回 ()
.如果真结束

' 禁用连接按钮,启用断开和发送按钮
btnConnect.禁止 = #真
btnDisconnect.禁止 = #假
btnSendMessage.禁止 = #假

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "【系统消息】已成功连接到服务器!" + #换行符
edtChatRecord.内容 = g_ChatRecord

调试输出 ("已成功连接到服务器!IP:", 服务器IP, " 端口:", 服务器端口)

.子程序 _btnDisconnect_被单击
' 断开连接
sckClient.断开 ()

' 禁用断开和发送按钮,启用连接按钮
btnConnect.禁止 = #假
btnDisconnect.禁止 = #真
btnSendMessage.禁止 = #真

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "【系统消息】已断开与服务器的连接!" + #换行符
edtChatRecord.内容 = g_ChatRecord

调试输出 ("已断开与服务器的连接!")

.子程序 _btnSendMessage_被单击
.局部变量 消息内容, 文本型

' 检查消息内容是否为空
消息内容 = txtMessage.内容
.如果真 (消息内容 = "")
    信息框 ("请输入消息内容!", 0, "错误提示")
    返回 ()
.如果真结束

' 发送消息
sckClient.发送数据 (到字节集 (消息内容, #UTF_8, ))

' 添加聊天记录
g_ChatRecord = g_ChatRecord + "【我】" + 消息内容 + #换行符
edtChatRecord.内容 = g_ChatRecord

' 清空消息输入框
txtMessage.内容 = ""

调试输出 ("发送消息:" + 消息内容)

.子程序 _sckClient_连接成功
' 连接成功事件(与_ btnConnect_被单击事件一起触发)
调试输出 ("连接成功事件触发!")

.子程序 _sckClient_连接断开
' 连接断开事件(与_ btnDisconnect_被单击事件一起触发)
调试输出 ("连接断开事件触发!")

.子程序 _sckClient_数据到达
.局部变量 接收数据, 字节集
.局部变量 消息内容, 文本型

' 接收数据
接收数据 = sckClient.接收数据 ()
消息内容 = 到文本 (接收数据, #UTF_8, )

' 检查是否是系统消息
.如果真 (取文本左边 (消息内容, 8) = "[SYSTEM]")
    ' 系统消息,显示黄色文本
    g_ChatRecord = g_ChatRecord + 取文本右边 (消息内容, 取文本长度 (消息内容) - 8) + #换行符
    edtChatRecord.内容 = g_ChatRecord
    edtChatRecord.颜色 = #黄色
.如果真结束
.如果真 (取文本左边 (消息内容, 8) ≠ "[SYSTEM]")
    ' 普通消息,显示黑色文本
    g_ChatRecord = g_ChatRecord + 消息内容 + #换行符
    edtChatRecord.内容 = g_ChatRecord
    edtChatRecord.颜色 = #黑色
.如果真结束

调试输出 ("接收消息:" + 消息内容)

5.4.4 TCP聊天工具调试与运行

  1. 先运行服务器端程序,点击"启动监听"
  2. 再运行客户端程序,输入服务器IP(127.0.0.1)和端口(8888),点击"连接服务器"
  3. 可以同时运行多个客户端程序,实现群聊功能
  4. 发送消息,查看聊天记录
  5. 断开连接,查看系统消息

5.5 UDP通信

UDP通信是一种不可靠的无连接的通信方式,速度快,适合开发对数据可靠性要求不高但对速度要求高的应用,如视频通话、音频直播、游戏数据传输。

5.5.1 UDP广播工具实战

设计思路
  • 使用UDP组件发送广播数据包
  • 使用UDP组件接收广播数据包
  • 显示发送和接收的数据包信息
创建工程与添加组件
  1. 创建一个新的Windows窗口程序工程
  2. 加载必要的支持库:系统核心支持库网络通信支持库
  3. 添加以下组件:
    • 标签组件:2个,分别用于显示"广播端口"和"数据包信息"
    • 文本框组件:2个,分别用于输入广播端口和数据包内容
    • 编辑框组件:1个,用于显示数据包信息
    • 按钮组件:2个,分别用于"发送广播"和"接收广播"
    • UDP组件:1个,用于发送和接收数据包
设置组件属性
组件名称 属性名 属性值
标签1 标题 广播端口
标签1 名称 lblPort
标签2 标题 数据包内容
标签2 名称 lblPacketContent
标签3 标题 数据包信息
标签3 名称 lblPacketInfo
文本框1 名称 txtPort
文本框1 内容 9999
文本框2 名称 txtContent
文本框2 内容 这是一个UDP广播数据包!
编辑框1 名称 edtPacketInfo
编辑框1 是否允许多行 #真
编辑框1 滚动条 #垂直滚动条
按钮1 名称 btnSendBroadcast
按钮1 标题 发送广播
按钮2 名称 btnReceiveBroadcast
按钮2 标题 接收广播
按钮2 禁止 #真
UDP组件1 名称 udpBroadcast
编写代码
e 复制代码
.版本 2
.支持库 spec
.支持库 internet
.支持库 eNetCom

' 数据包信息
.程序集变量 g_PacketInfo, 文本型

.子程序 __启动窗口_创建完毕
' 初始化组件属性
_启动窗口.标题 = "UDP广播工具"
_启动窗口.宽度 = 550
_启动窗口.高度 = 450
_启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2
_启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2

' 初始化数据包信息
g_PacketInfo = "工具启动时间:" + 到文本 (取现行时间 (), , "yyyy年MM月dd日 HH时mm分ss秒") + #换行符

.子程序 _btnSendBroadcast_被单击
.局部变量 广播端口, 整数型
.局部变量 数据包内容, 文本型

' 检查广播端口是否合法
广播端口 = 到数值 (txtPort.内容)
.如果真 (广播端口 < 1024 或 广播端口 > 65535)
    信息框 ("广播端口必须在1024~65535之间!", 0, "错误提示")
    返回 ()
.如果真结束

' 检查数据包内容是否为空
数据包内容 = txtContent.内容
.如果真 (数据包内容 = "")
    信息框 ("请输入数据包内容!", 0, "错误提示")
    返回 ()
.如果真结束

' 发送广播数据包(广播地址为255.255.255.255)
udpBroadcast.发送数据 ("255.255.255.255", 广播端口, 到字节集 (数据包内容, #UTF_8, ))

' 添加数据包信息
g_PacketInfo = g_PacketInfo + "【发送数据包】时间:" + 到文本 (取现行时间 (), , "HH时mm分ss秒") + " 目标地址:255.255.255.255:" + 到文本 (广播端口) + " 内容:" + 数据包内容 + #换行符
edtPacketInfo.内容 = g_PacketInfo

调试输出 ("发送广播数据包!目标地址:255.255.255.255:" + 到文本 (广播端口) + " 内容:" + 数据包内容)

.子程序 _btnReceiveBroadcast_被单击
.局部变量 监听端口, 整数型

' 检查监听端口是否合法
监听端口 = 到数值 (txtPort.内容)
.如果真 (监听端口 < 1024 或 监听端口 > 65535)
    信息框 ("监听端口必须在1024~65535之间!", 0, "错误提示")
    返回 ()
.如果真结束

' 绑定监听端口
.如果真 (udpBroadcast.绑定端口 (监听端口) = #假)
    信息框 ("绑定监听端口失败!请检查端口是否被占用。", 0, "错误提示")
    返回 ()
.如果真结束

' 禁用发送按钮,启用接收按钮
btnSendBroadcast.禁止 = #真
btnReceiveBroadcast.禁止 = #真

' 添加数据包信息
g_PacketInfo = g_PacketInfo + "【系统消息】已开始监听广播,端口:" + 到文本 (监听端口) + ",等待接收数据包... " + #换行符
edtPacketInfo.内容 = g_PacketInfo

调试输出 ("已开始监听广播,端口:", 监听端口)

.子程序 _udpBroadcast_数据到达
.局部变量 发送方IP, 文本型
.局部变量 发送方端口, 整数型
.局部变量 接收数据, 字节集
.局部变量 数据包内容, 文本型

' 获取发送方IP和端口
发送方IP = udpBroadcast.取发送方IP ()
发送方端口 = udpBroadcast.取发送方端口 ()

' 接收数据
接收数据 = udpBroadcast.接收数据 ()
数据包内容 = 到文本 (接收数据, #UTF_8, )

' 添加数据包信息
g_PacketInfo = g_PacketInfo + "【接收数据包】时间:" + 到文本 (取现行时间 (), , "HH时mm分ss秒") + " 发送方地址:" + 发送方IP + ":" + 到文本 (发送方端口) + " 内容:" + 数据包内容 + #换行符
edtPacketInfo.内容 = g_PacketInfo

调试输出 ("接收数据包!发送方地址:" + 发送方IP + ":" + 到文本 (发送方端口) + " 内容:" + 数据包内容)

5.5.2 UDP广播工具调试与运行

  1. 运行两个或更多的UDP广播工具实例
  2. 在每个实例中输入相同的广播端口(如9999)
  3. 在一个实例中点击"发送广播",其他实例会接收到广播数据包
  4. 在一个实例中点击"接收广播",可以持续接收广播数据包

5.6 网络通信常见问题与解决方案

5.6.1 网络连接失败

问题现象:程序无法连接到服务器,提示"连接服务器失败"或"端口绑定失败"。

原因

  • 服务器未启动监听
  • 服务器IP或端口输入错误
  • 网络连接不稳定
  • 防火墙拦截了网络通信
  • 端口被其他程序占用

解决方案

  • 确保服务器已启动监听
  • 检查服务器IP和端口输入是否正确
  • 检查网络连接是否稳定
  • 关闭防火墙或添加防火墙例外
  • 更换未被占用的端口

5.6.2 请求超时

问题现象:HTTP请求或TCP连接超时,提示"请求超时"或"连接超时"。

原因

  • 服务器响应慢
  • 网络延迟高
  • 防火墙拦截了响应数据包
  • 请求参数不正确

解决方案

  • 优化服务器响应速度
  • 检查网络延迟是否过高
  • 关闭防火墙或添加防火墙例外
  • 检查请求参数是否正确
  • 添加超时设置和重试机制

5.6.3 数据解析错误

问题现象:HTTP响应数据解析错误,提示"JSON解析失败"或"HTML解析失败"。

原因

  • 响应数据格式不正确
  • 请求参数不正确
  • 服务器返回了错误信息
  • 编码方式不匹配

解决方案

  • 检查响应数据格式是否正确
  • 检查请求参数是否正确
  • 处理服务器返回的错误信息
  • 确保编码方式匹配(如UTF-8、ANSI、Unicode)

5.6.4 防火墙拦截

问题现象:程序无法发送或接收网络数据,提示"网络连接失败"或"数据到达事件未触发"。

原因

  • 防火墙拦截了程序的网络通信
  • 程序没有网络通信权限

解决方案

  • 关闭防火墙
  • 添加防火墙例外(允许程序发送和接收网络数据)
  • 以管理员身份运行程序

5.7 总结

✅ 本章详细介绍了易语言网络通信编程的基础概念和常用方法,包括HTTP/HTTPS通信TCP通信UDP通信。通过学习,我们掌握了:

  • 网络通信的基础概念(IP地址、端口、协议、客户端/服务器模型)
  • HTTP/HTTPS通信的常用方法(GET/POST请求、响应解析)
  • TCP通信组件的使用(客户组件、服务端组件)
  • UDP通信组件的使用(UDP组件)
  • 综合运用所学知识,完成了三个实战案例:
    • 调用天气API获取实时天气
    • 开发一个简单的TCP聊天工具(服务端+客户端)
    • 开发一个简单的UDP广播工具
  • 掌握了网络通信的常见问题及解决方案

网络通信编程是现代软件开发的重要环节,易语言提供了丰富的网络通信组件和命令,让中文开发者能够快速上手。在实际开发中,还可以使用WebSocket支持库开发实时双向通信应用,或使用爬虫支持库开发数据采集应用。

希望大家能够认真学习本章内容,多动手实践,理解网络通信的核心原理,为后续学习高级功能(如数据库远程连接、云服务对接)打下坚实的基础。

相关推荐
爱吃大芒果5 小时前
Flutter for OpenHarmony 实战: mango_shop 通用组件库的封装与跨端复用
开发语言·flutter·dart
DevilSeagull5 小时前
HTTP/HTTPS数据包拓展
网络·网络协议·http·https·web渗透·we
雨季6665 小时前
Flutter 三端应用实战:OpenHarmony “安全文本溢出处理调节器”
开发语言·前端·安全·flutter·交互
小小码农Come on5 小时前
QT控件之QTabWidget使用
开发语言·qt
码农水水5 小时前
从 OpenFeign 到 RestClient:Spring Cloud 新时代的轻量化 HTTP 调用方案
java·运维·后端·spring·http·spring cloud·面试
晔子yy5 小时前
聊聊Java的内存模型
java·开发语言
REDcker5 小时前
HTTP 状态码清单大全
网络·网络协议·http
难得的我们5 小时前
基于C++的区块链实现
开发语言·c++·算法
Acrelhuang5 小时前
工厂配电升级优选 安科瑞智能断路器安全提效又节能-安科瑞黄安南
大数据·运维·开发语言·人工智能·物联网