|

楼主 |
发表于 2017-11-22 15:11:42
|
显示全部楼层
26.7.2 STM32F429开发板实验
配套例子:
V6-1033_RL-TCPnet实验_DHCP应用(RTX)
实验目的:
1. 学习RL-TCPnet的DHCP应用。
实验内容:
1. DHCP已经使能,如果插上网线8秒内无法从路由器/交换机获得IP地址,将使用固定IP:192.168.1.100。此固定IP是在配置向导文件Net_Config.c里面设置的。
2. 本例程创建了一个socket服务器,采用TCP通信协议,而且使能了局域网域名NetBIOS,用户只需在电脑端ping armfly就可以获得板子的IP地址,本地端口被设置为1024。
3. 用户可以在电脑端用网络调试软件创建TCP Client连接此服务器。
4. 网络调试助手发送命令字符1,板子回复字符1到8以及回车和换行两个字符,共10个。
5. 网络调试助手发送命令字符2,板子回复1024个字符,前4个字符是abcd,最后4个字符是efgh,中间的1016个全部是字符0。
实验操作:
详见本章节26.6小节。
配置向导文件设置(Net_Config.c):
详见本章节26.3小节。
调试文件设置(Net_Debug.c):
详见本章节26.4小节。
RTX配置:
RTX配置向导详情如下:
Task Configuration
(1)Number of concurrent running tasks
允许创建7个任务,实际创建了如下6个任务:
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :按键检测。
AppTaskSocket任务 :socket服务器任务
AppTaskTCPMain任务:RL-TCPnet网络主任务。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现RL-TCPnet的时间基准更新。
(2)Number of tasks with user-provided stack
创建的6个任务都是采用自定义堆栈方式。
(3)Run in privileged mode
设置任务运行在非特权级模式。
RTX任务调试信息:
程序设计:
任务栈大小分配:
static uint64_t AppTaskUserIFStk[1024/8]; /* 任务栈 */
static uint64_t AppTaskLEDStk[1024/8]; /* 任务栈 */
static uint64_t AppTaskMsgProStk[1024/8]; /* 任务栈 */
static uint64_t AppTaskSocketStk[2048/8]; /* 任务栈 */
static uint64_t AppTaskTCPMainStk[2048/8]; /* 任务栈 */
static uint64_t AppTaskStartStk[1024/8]; /* 任务栈 */
将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数、浮点运算和uint64_t类型数据运算会出问题。
系统栈大小分配:
RTX初始化:
- [size=3][b]/*[/b][/size]
- [size=3][b]*********************************************************************************************************[/b][/size]
- [size=3][b]* 函 数 名: main[/b][/size]
- [size=3][b]* 功能说明: 标准c程序入口。[/b][/size]
- [size=3][b]* 形 参: 无[/b][/size]
- [size=3][b]* 返 回 值: 无[/b][/size]
- [size=3][b]*********************************************************************************************************[/b][/size]
- [size=3][b]*/[/b][/size]
- [size=3][b]int main (void)[/b][/size]
- [size=3][b]{[/b][/size]
- [size=3][b]/* 初始化外设 */[/b][/size]
- [size=3][b]bsp_Init();[/b][/size]
- [size=3][b]/* 创建启动任务 */[/b][/size]
- [size=3][b]os_sys_init_user (AppTaskStart, /* 任务函数 */[/b][/size]
- [size=3][b]6, /* 任务优先级 */[/b][/size]
- [size=3][b]&AppTaskStartStk, /* 任务栈 */[/b][/size]
- [size=3][b]sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */[/b][/size]
- [size=3][b]while(1);[/b][/size]
- [size=3][b]}[/b][/size]
复制代码
硬件外设初始化
硬件外设的初始化是在 bsp.c 文件实现:
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 函 数 名: bsp_Init[/size]
- [size=3]* 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次[/size]
- [size=3]* 形 参:无[/size]
- [size=3]* 返 回 值: 无[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]void bsp_Init(void)[/size]
- [size=3]{[/size]
- [size=3]/*[/size]
- [size=3]由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。[/size]
- [size=3]启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。[/size]
- [size=3]系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件[/size]
- [size=3]*/[/size]
- [size=3]/* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/[/size]
- [size=3]NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);[/size]
- [size=3]SystemCoreClockUpdate(); /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */[/size]
- [size=3]bsp_InitDWT(); /* 初始化DWT */[/size]
- [size=3]bsp_InitUart(); /* 初始化串口 */[/size]
- [size=3]bsp_InitKey(); /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */[/size]
- [size=3]bsp_InitExtIO(); /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */[/size]
- [size=3]bsp_InitLed(); /* 初始LED指示灯端口 */[/size]
- [size=3]}[/size]
复制代码
RTX任务创建:
- [size=3][b]/*[/b][/size]
- [size=3][b]*********************************************************************************************************[/b][/size]
- [size=3][b]* 函 数 名: AppTaskCreate[/b][/size]
- [size=3][b]* 功能说明: 创建应用任务[/b][/size]
- [size=3][b]* 形 参: 无[/b][/size]
- [size=3][b]* 返 回 值: 无[/b][/size]
- [size=3][b]*********************************************************************************************************[/b][/size]
- [size=3][b]*/[/b][/size]
- [size=3][b]static void AppTaskCreate (void)[/b][/size]
- [size=3][b]{[/b][/size]
- [size=3][b]HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */[/b][/size]
- [size=3][b]1, /* 任务优先级 */[/b][/size]
- [size=3][b]&AppTaskUserIFStk, /* 任务栈 */[/b][/size]
- [size=3][b]sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */[/b][/size]
- [size=3][b]HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */[/b][/size]
- [size=3][b]2, /* 任务优先级 */[/b][/size]
- [size=3][b]&AppTaskLEDStk, /* 任务栈 */[/b][/size]
- [size=3][b]sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */[/b][/size]
- [size=3][b]HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */[/b][/size]
- [size=3][b]3, /* 任务优先级 */[/b][/size]
- [size=3][b]&AppTaskMsgProStk, /* 任务栈 */[/b][/size]
- [size=3][b]sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */[/b][/size]
- [size=3][b]HandleTaskSocket = os_tsk_create_user(AppTaskSocket, /* 任务函数 */[/b][/size]
- [size=3][b]4, /* 任务优先级 */[/b][/size]
- [size=3][b]&AppTaskSocketStk, /* 任务栈 */[/b][/size]
- [size=3][b]sizeof(AppTaskSocketStk)); /* 任务栈大小,单位字节数 */[/b][/size]
- [size=3][b]HandleTaskTCPMain = os_tsk_create_user(AppTaskTCPMain, /* 任务函数 */[/b][/size]
- [size=3][b]5, /* 任务优先级 */[/b][/size]
- [size=3][b]&AppTaskTCPMainStk, /* 任务栈 */[/b][/size]
- [size=3][b]sizeof(AppTaskTCPMainStk)); /* 任务栈大小,单位字节数 */[/b][/size]
- [size=3][b]}[/b][/size]
复制代码
六个RTX任务的实现:
RL-TCPnet网络主任务
这里专门创建了一个app_tcpnet_lib.c文件用于RL-TCPnet的网络主任务,实现动态IP获取和网络协议栈主函数main_TcpNet的调用。
- [size=3]#include "includes.h"[/size]
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 用于本文件的调试[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]#if 1[/size]
- [size=3]#define printf_tcpdbg printf[/size]
- [size=3]#else[/size]
- [size=3]#define printf_tcpdbg(...)[/size]
- [size=3]#endif[/size]
- [size=3]/*[/size]
- [size=3]**********************************************************************************************************[/size]
- [size=3]外部调用[/size]
- [size=3]**********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]#define DHCP_TOUT 80 /* DHCP动态IP获取的溢出时间设置为8秒 */[/size]
- [size=3]#define MY_IP localm[NETIF_ETH].IpAdr[/size]
- [size=3]extern LOCALM localm[];[/size]
- [size=3]/*[/size]
- [size=3]**********************************************************************************************************[/size]
- [size=3]变量[/size]
- [size=3]**********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]uint32_t dhcp_tout;[/size]
- [size=3]uint8_t DHCP_Status[2][40] = {"IP: 192.168.X.X",[/size]
- [size=3]"Waiting for DHCP"};[/size]
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 函 数 名: main[/size]
- [size=3]* 功能说明: 标准c程序入口。[/size]
- [size=3]* 形 参: 无[/size]
- [size=3]* 返 回 值: 无[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]static void dhcp_check(void)[/size]
- [size=3]{[/size]
- [size=3]/* 检测是否通过DHCP自动获得IP */[/size]
- [size=3]if (mem_test (&MY_IP, 0, IP_ADRLEN) == __FALSE && !(dhcp_tout & 0x80000000))[/size]
- [size=3]{[/size]
- [size=3]/* 已经获得IP */[/size]
- [size=3]dhcp_tout = 0;[/size]
- [size=3]sprintf((char *)DHCP_Status[0],"%d.%d.%d.%d", MY_IP[0], MY_IP[1],[/size]
- [size=3]MY_IP[2], MY_IP[3]);[/size]
- [size=3]sprintf((char *)DHCP_Status[1],"DHCP Success");[/size]
- [size=3]printf_tcpdbg("%s\\r\\n", DHCP_Status[0]);[/size]
- [size=3]printf_tcpdbg("%s\\r\\n", DHCP_Status[1]);[/size]
- [size=3]return;[/size]
- [size=3]}[/size]
- [size=3]/* 每100ms进行一次减减操作 */[/size]
- [size=3]if (--dhcp_tout == 0)[/size]
- [size=3]{[/size]
- [size=3]/* 设置的8秒自动获取IP时间已经到了,禁止DHCP,准备使用固定IP */[/size]
- [size=3]dhcp_disable ();[/size]
- [size=3]sprintf((char *)DHCP_Status[1],"DHCP Failed" );[/size]
- [size=3]/* 更新溢出时间,将固定IP的分配时间也设置为8秒 */[/size]
- [size=3]dhcp_tout = 80 | 0x80000000;[/size]
- [size=3]return;[/size]
- [size=3]}[/size]
- [size=3]/* 设置固定IP的8秒时间到 */[/size]
- [size=3]if (dhcp_tout == 0x80000000)[/size]
- [size=3]{[/size]
- [size=3]dhcp_tout = 0;[/size]
- [size=3]sprintf((char *)DHCP_Status[0],"%d.%d.%d.%d", MY_IP[0], MY_IP[1],[/size]
- [size=3]MY_IP[2], MY_IP[3]);[/size]
- [size=3]sprintf((char *)DHCP_Status[1],"DHCP Failed Use static IP");[/size]
- [size=3]printf_tcpdbg("%s\\r\\n", DHCP_Status[0]);[/size]
- [size=3]printf_tcpdbg("%s\\r\\n", DHCP_Status[1]);[/size]
- [size=3]}[/size]
- [size=3]}[/size]
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 函 数 名: TCPnetTest[/size]
- [size=3]* 功能说明: 主要实现动态IP获取和网络协议栈主函数main_TcpNet的调用。[/size]
- [size=3]* 形 参: 无[/size]
- [size=3]* 返 回 值: 无[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]void TCPnetTest(void)[/size]
- [size=3]{[/size]
- [size=3]uint32_t tstart, tend;[/size]
- [size=3]/* 初始化变量 */[/size]
- [size=3]dhcp_tout = DHCP_TOUT;[/size]
- [size=3]tstart = os_time_get();[/size]
- [size=3]while (1)[/size]
- [size=3]{[/size]
- [size=3]/* 每100ms做一次DHCP检测 */[/size]
- [size=3]if(dhcp_tout != 0)[/size]
- [size=3]{[/size]
- [size=3]tend = os_time_get() - tstart;[/size]
- [size=3]//printf_tcpdbg("%x %d\\r\\n", dhcp_tout, tend);[/size]
- [size=3]if(tend >= 100)[/size]
- [size=3]{[/size]
- [size=3]tstart = os_time_get();[/size]
- [size=3]dhcp_check();[/size]
- [size=3]}[/size]
- [size=3]}[/size]
- [size=3]os_evt_wait_and(0x0001, 0xFFFF);[/size]
- [size=3]while (main_TcpNet() == __TRUE);[/size]
- [size=3]}[/size]
- [size=3]}[/size]
复制代码
Socket 服务器任务
这里专门创建了一个app_socket_lib.c文件用于socket服务器任务。
- [size=3]#include "includes.h"[/size]
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 用于本文件的调试[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]#if 1[/size]
- [size=3]#define printf_debug printf[/size]
- [size=3]#else[/size]
- [size=3]#define printf_debug(...)[/size]
- [size=3]#endif[/size]
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 宏定义,本地端口[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]/* 这个是本地端口 */[/size]
- [size=3]#define LocalPort_NUM 1001[/size]
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 变量[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]/* RL-TCPnet API的返回值 */[/size]
- [size=3]const char * ReVal_Table[]=[/size]
- [size=3]{[/size]
- [size=3]" 0: SCK_SUCCESS Success ",[/size]
- [size=3]"-1: SCK_ERROR General Error ",[/size]
- [size=3]"-2: SCK_EINVALID Invalid socket descriptor ",[/size]
- [size=3]"-3: SCK_EINVALIDPARA Invalid parameter ",[/size]
- [size=3]"-4: SCK_EWOULDBLOCK It would have blocked. ",[/size]
- [size=3]"-5: SCK_EMEMNOTAVAIL Not enough memory in memory pool ",[/size]
- [size=3]"-6: SCK_ECLOSED Connection is closed or aborted ",[/size]
- [size=3]"-7: SCK_ELOCKED Socket is locked in RTX environment ",[/size]
- [size=3]"-8: SCK_ETIMEOUT Socket, Host Resolver timeout ",[/size]
- [size=3]"-9: SCK_EINPROGRESS Host Name resolving in progress ",[/size]
- [size=3]"-10: SCK_ENONAME Host Name not existing ",[/size]
- [size=3]};[/size]
- [size=3]uint8_t sendbuf[1024];[/size]
- [size=3]/*[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]* 函 数 名: SocketTest[/size]
- [size=3]* 功能说明: Socket应用[/size]
- [size=3]* 形 参: 无[/size]
- [size=3]* 返 回 值: 无[/size]
- [size=3]*********************************************************************************************************[/size]
- [size=3]*/[/size]
- [size=3]void SocketTest(void)[/size]
- [size=3]{[/size]
- [size=3]char dbuf[10];[/size]
- [size=3]int len;[/size]
- [size=3]int sock, sd, res;[/size]
- [size=3]SOCKADDR_IN addr;[/size]
- [size=3]SOCKADDR_IN ReAddr;[/size]
- [size=3]while (1)[/size]
- [size=3]{[/size]
- [size=3]/* 创建一个socket[/size]
- [size=3]第1个参数AF_INET:当前仅支持这个类型的地址族。[/size]
- [size=3]第2个参数SOCK_STREAM:表示数据流通信类型,即使用的TCP。[/size]
- [size=3]第3个参数0 :配置为0的话,自动跟第2个参数进行协议匹配,这里就是TCP协议。[/size]
- [size=3]*/[/size]
- [size=3]sock = socket (AF_INET, SOCK_STREAM, 0);[/size]
- [size=3]/* 端口号设置为1001 */[/size]
- [size=3]addr.sin_port = htons(LocalPort_NUM);[/size]
- [size=3]/* 与函数socket中的AF_INET作用一样 */[/size]
- [size=3]addr.sin_family = PF_INET;[/size]
- [size=3]/*[/size]
- [size=3]INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或所有地址,[/size]
- [size=3]任意地址。用在这里的话就表示监控端口号为ddr.sin_port的所有IP地址消息。一般主要用[/size]
- [size=3]于有多个网卡或者IP地址的情况。开发板只用了DM9161的网口,就是监听这个网口的IP地址。[/size]
- [size=3]*/[/size]
- [size=3]addr.sin_addr.s_addr = INADDR_ANY;[/size]
- [size=3]/* 给socket绑定IP和端口号 */[/size]
- [size=3]bind (sock, (SOCKADDR *)&addr, sizeof(addr));[/size]
- [size=3]/* 设置监听,最大监听1个连接 */[/size]
- [size=3]listen (sock, 1);[/size]
- [size=3]/*[/size]
- [size=3]等待soket连接请求,有的话,自动创建1个新的socket进行连接通信,没有的话,等待连接。[/size]
- [size=3]注意,能够accept的个数受到listen函数的限制,而listen函数又受到Net_Config.c中宏定义[/size]
- [size=3]BSD_NUMSOCKS 的限制。[/size]
- [size=3]*/[/size]
- [size=3]len = sizeof(ReAddr);[/size]
- [size=3]sd = accept (sock, (SOCKADDR *)&ReAddr, &len);[/size]
- [size=3]printf_debug ("远程客户端请求连接IP: %d.%d.%d.%d\\n", ReAddr.sin_addr.s_b1,[/size]
- [size=3]ReAddr.sin_addr.s_b2,[/size]
- [size=3]ReAddr.sin_addr.s_b3,[/size]
- [size=3]ReAddr.sin_addr.s_b4);[/size]
- [size=3]printf_debug ("远程客户端端口号: %d\\n", ntohs(ReAddr.sin_port));[/size]
- [size=3]/* 关闭监听socket,这个监听socket是调用函数socket后自动创建的 */[/size]
- [size=3]closesocket (sock);[/size]
- [size=3]sock = sd;[/size]
- [size=3]while (1)[/size]
- [size=3]{[/size]
- [size=3]/*[/size]
- [size=3]socket数据接收函数,如果recv工作在阻塞模式,使用这个函数注意以下事项:[/size]
- [size=3]1. 此函数的溢出时间受到Net_Config.c中宏定义 BSD_RCVTOUT 的限制。溢出时间到会自动退出。[/size]
- [size=3]2. 这个函数接收到一次数据包就会返回,大于或者小于设置的缓冲区大小都没有关系,如果数据量[/size]
- [size=3]大于接收缓冲区大小,用户只需多次调用函数recv进行接收即可。[/size]
- [size=3]3. 实际接收到数据大小通过判断此函数的返回值即可。[/size]
- [size=3]*/[/size]
- [size=3]res = recv (sock, dbuf, sizeof(dbuf), 0);[/size]
- [size=3]if (res <= 0)[/size]
- [size=3]{[/size]
- [size=3]printf_debug("退出接收函数,重新开始监听%s\\r\\n", ReVal_Table[abs(res)]);[/size]
- [size=3]break;[/size]
- [size=3]}[/size]
- [size=3]else[/size]
- [size=3]{[/size]
- [size=3]printf_debug("Receive Data Length = %d\\r\\n", res);[/size]
- [size=3]switch(dbuf[0])[/size]
- [size=3]{[/size]
- [size=3]/* 字符命令 1 */[/size]
- [size=3]case '1':[/size]
- [size=3]sendbuf[0] = '1';[/size]
- [size=3]sendbuf[1] = '2';[/size]
- [size=3]sendbuf[2] = '3';[/size]
- [size=3]sendbuf[3] = '4';[/size]
- [size=3]sendbuf[4] = '5';[/size]
- [size=3]sendbuf[5] = '6';[/size]
- [size=3]sendbuf[6] = '7';[/size]
- [size=3]sendbuf[7] = '8';[/size]
- [size=3]sendbuf[8] = '\\r';[/size]
- [size=3]sendbuf[9] = '\\n';[/size]
- [size=3]res = send (sock, (char *)sendbuf, 10, 0);[/size]
- [size=3]if (res < 0)[/size]
- [size=3]{[/size]
- [size=3]printf_debug("函数send发送数据失败\\r\\n");[/size]
- [size=3]}[/size]
- [size=3]else[/size]
- [size=3]{[/size]
- [size=3]printf_debug("函数send发送数据成功\\r\\n");[/size]
- [size=3]}[/size]
- [size=3]break;[/size]
- [size=3]/* 字符命令 2 */[/size]
- [size=3]case '2':[/size]
- [size=3]/* 将数据缓冲区清成字符0,方便网络调试助手查看数据 */[/size]
- [size=3]len = sizeof(sendbuf);[/size]
- [size=3]memset(sendbuf, 48, len);[/size]
- [size=3]/* 这里仅初始化了数据包的前4个字节和最后4个字节 */[/size]
- [size=3]sendbuf[0] = 'a';[/size]
- [size=3]sendbuf[1] = 'b';[/size]
- [size=3]sendbuf[2] = 'c';[/size]
- [size=3]sendbuf[3] = 'd';[/size]
- [size=3]sendbuf[len - 4] = 'e';[/size]
- [size=3]sendbuf[len - 3] = 'f';[/size]
- [size=3]sendbuf[len - 2] = 'g';[/size]
- [size=3]sendbuf[len - 1] = 'h';[/size]
- [size=3]res = send (sock, (char *)sendbuf, len, 0);[/size]
- [size=3]if (res < 0)[/size]
- [size=3]{[/size]
- [size=3]printf_debug("函数send发送数据失败%s\\r\\n", ReVal_Table[abs(res)]);[/size]
- [size=3]}[/size]
- [size=3]else[/size]
- [size=3]{[/size]
- [size=3]printf_debug("函数send成功发送数据 = %d字节\\r\\n", res);[/size]
- [size=3]}[/size]
- [size=3]break;[/size]
- [size=3]/* 其它数值不做处理 */[/size]
- [size=3]default:[/size]
- [size=3]break;[/size]
- [size=3]}[/size]
- [size=3]}[/size]
- [size=3]}[/size]
- [size=3]/*[/size]
- [size=3]溢出时间到,远程设备断开连接等,程序都会执行到这里,我们在这里关闭socket,[/size]
- [size=3]程序返回到第一个大while循环的开头重新创建socket并监听。[/size]
- [size=3]*/[/size]
- [size=3]closesocket (sock);[/size]
- [size=3]}[/size]
- [size=3]}[/size]
复制代码 |
|