打印

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

[复制链接]
367|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
石头张|  楼主 | 2018-7-27 08:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本设计参考以下帖子的思路:服务器每检测到一个客户端连接请求建立一个任务
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!

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

446

主题

446

帖子

0

粉丝