OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9232|回复: 6

STM32F407探索者TCP并发服务器精简版问世!!!可以多客户端通信!客户端和客户端也可通信!网线热插拔!功能强大!通俗易懂!

[复制链接]

9

主题

209

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1358
金钱
1358
注册时间
2015-12-19
在线时间
108 小时
发表于 2017-3-11 16:38:12 | 显示全部楼层 |阅读模式
本帖最后由 yangkefeng 于 2017-3-11 16:48 编辑

本设计参考以下帖子的思路:服务器每检测到一个客户端连接请求建立一个任务
http://www.openedv.com/forum.php ... =%B7%FE%CE%F1%C6%F7


由于以上版本可读性感觉不是很好,可移植性也不好,而且需要实现客户端之间的互通,我就自己琢磨着写了一个,过程中还是有很多问题的。
新思路:TCP CLIENT结构体加入编号,用新结构体保存TCP CLIENT的地址,保存TCP CLIENT的连接状态,这样根据状态就很容易可以找到哪个TCP需要进行通信。

#define CLIENTMAX   40 //最大客户端数量
typedef struct  
{
        struct netconn *conn;//连接结构体
        OS_TCB    *clientTCB;//任务控制块
        CPU_STK   *clientSTK;//任务堆栈
        u8               num;//CLIENT编号
}tcp_client;



typedef struct  
{
        tcp_client  *client[CLIENTMAX];//客户端地址保存
        u8            state[CLIENTMAX];//客户端状态
}client_ad;


网线插拔可以读取LAN8720寄存器判断:以下直接通过LED1亮和灭体现网线连接状态
LED1 = ~(ETH_ReadPHYRegister(0x00,29)>>6)%2; //网线热插拔检测

断开网线后需要删除所有客户端任务 并释放内存。其他任务不需要改动,重新连接之后可以正常通信(亲测通过)
断开网线后做如下处理:
for(clientnum=1;clientnum<CLIENTMAX;clientnum++)    //循环检测客户端连接状态
{                                                                          //从1到40循环检测
        if(clientad.state[clientnum]==1)                  //判断连接状态
        {                                                           //已连接
                OSTaskDel(clientad.client[clientnum]->clientTCB,&oserr); //删除客户端任务
                myfree(SRAMCCM, (clientad.client[clientnum]->clientTCB));//释放clientTCB内存
                myfree(SRAMCCM, (clientad.client[clientnum]->clientSTK));//释放clientSTK内存
                myfree(SRAMCCM, clientad.client[clientnum]);                      //释放 结构体 内存
                printf("%d号客户端已删除\r\n",clientnum);            //打印信息
                clientad.state[clientnum]=0;                             //客户端连接状态清0 表示已断开连接
        }
}


实现客户端与客户端之间的通信主要通过以下方式(我没有测试开启40个客户端通信  不过9个客户端已经亲测通过)
将 (某个客户端)的数据接收下来存入u8 rbuf[4],判断第一个是不是 'a' 第四个是不是'a' 第二个如果是0-9 如'5' 并且5号客户端已建立连接 就把第三个数据 发送到5号客户端。
这边我数据处理比较粗略,大家可以自己定协议处理。


if( rbuf[0]=='a' && rbuf[3]=='a' && ((rbuf[1]-0x30)==clientad.client[rbuf[1]-0x30]->num ) )
        netconn_write(clientad.client[rbuf[1]-0x30]->conn,rbuf+2,1,NETCONN_COPY);//向指定客户端发送数据(前提是该客户端已建立连接)


具体很多细节都在源码体现了,没用到LCD,所有信息都在串口1打印,在探索者开发板调的。

标准库+UCOSIII+LWIP!

图

并发服务器 (完美版).rar (1.04 MB, 下载次数: 957)
求指导!!!兄弟
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

42

主题

297

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2016-7-22
在线时间
318 小时
发表于 2017-3-12 09:38:57 | 显示全部楼层
顶~  我最近移植lwip出现了问题
回复 支持 反对

使用道具 举报

9

主题

209

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1358
金钱
1358
注册时间
2015-12-19
在线时间
108 小时
 楼主| 发表于 2017-3-12 13:37:07 | 显示全部楼层
hi我歌月徘徊 发表于 2017-3-12 09:38
顶~  我最近移植lwip出现了问题

相信你可以的   还是emWin移植麻烦  我都不打算移植   直接用左大神弄好的,吼吼
求指导!!!兄弟
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2020-4-23
在线时间
5 小时
发表于 2020-4-26 14:44:30 | 显示全部楼层
不错,收藏了!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2014-12-3
在线时间
2 小时
发表于 2021-1-11 15:25:42 | 显示全部楼层
楼主,STM32F407是不是最多有9个可以同时通信,我用STM32F103 内存64K的只能3个同时通信,STM32F407单片机内存192K刚好是STM32F103内存的3倍, 我没有STM32F407的板子能帮我验证确认下吗?谢谢!
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
398
金钱
398
注册时间
2020-3-12
在线时间
72 小时
发表于 2021-7-6 14:52:52 | 显示全部楼层
MARK,很好,学了下框架、思路,把我的LWIP_服务端+UCOS_II+热插拔改好了 感谢楼主
回复 支持 反对

使用道具 举报

3

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
249
金钱
249
注册时间
2019-7-21
在线时间
61 小时
发表于 2021-8-17 22:50:06 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 06:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表