stm32上实现TCP/IP通信的部分采坑心得

首先是stm32通过W5500模块建立tcp-server服务端(购买w5500模块后都有教程 本文提供面向stm32f103rdt6的双网口例程 提取码:ptj3)
在while(1)死循环中持续监听接入的client客户端
与arm-linux不同的是,STM32无法开启线程
如果多个client接入,需要创建多个socket包与不同的client连接
W5500自带8个socket,最多监听8个client客户端
以轮询的方式进行多客户端监听
假代码如下:

#include 
#include 
#include 
#include "main.h"
#include "tcp_demo.h"
#include "W5500_conf.h"
#include "w5500.h"
#include "socket.h"

/* 如果需要再监听一个客户端 则需要新建一个do_tcp_server函数并将其中的 SOCK_TCPS 换成其他 socket 即可*/
void do_tcp_server(void)
{
    uint16 len=0;
    W5500_Use_Flag = 2;
    switch(getSn_SR(SOCK_TCPS))                                 /*获取socket的状态*/
    {
        case SOCK_CLOSED:                                           /*socket处于关闭状态*/
            socket(SOCK_TCPS ,Sn_MR_TCP,local_port,Sn_MR_ND);       /*打开socket*/
          break;     
    
        case SOCK_INIT:                                             /*socket已初始化状态*/
             printf("SERVER处于监听状态\r\n");
             listen(SOCK_TCPS);                                     /*socket建立监听*/  
                                                                    //建立连接标志位
          break;
        
        case SOCK_ESTABLISHED:                                      /*socket处于连接建立状态*/
            //printf("处于建立连接状态\r\n");
            if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)
            {
                setSn_IR(SOCK_TCPS, Sn_IR_CON);                     /*清除接收中断标志位*/
            }
            len=getSn_RX_RSR(SOCK_TCPS);                            /*定义len为已接收数据的长度*/
            if(len>0)
            {
                recv(SOCK_TCPS,buff,len);
                buff[len]=0x00;                                     /*添加字符串结束符*/
                    /* 处理来自客户端的信息 */
            }
            
          break;
        
        case SOCK_CLOSE_WAIT:                                       /*socket处于等待关闭状态*/
            close(SOCK_TCPS);
          break;
    }
}  

int main(void)
{
    while(1)
    {   
        do_tcp_server();
    }
}

其中W5500可供选择的socket:

/*Socket 端口选择,可按自己的习惯定义*/
#define SOCK_TCPS             0
#define SOCK_TCPC             1
#define SOCK_UDPS             2
#define SOCK_WEIBO            2
#define SOCK_DHCP             3
#define SOCK_HTTPS            4
#define SOCK_DNS              5
#define SOCK_SMTP             6
#define SOCK_NTP              7

雷区1

不要用一个socket轮询访问多个不同ip,不论是客户端还是服务端。
单个socket需要进行多次的连接(connect)和断开连接(close)操作,非常浪费时间,并且容易引起逻辑缠绕。
最好的方式就是一个ip对应一个socket,建立成功连接了,就保持连接,既高效,逻辑耦合也低,只需轮询访问不同socket即可。

雷区2

通过TCP/IP协议连接时,连接成功后,即等于成功建立SOCKET保持通信。如若重启设备,形成新的SOCKET连接,则连接是否成功取决于对方设备(对方设备作为SERVER端)是否支持多CLIENT访问,若不支持会导致连接失败,需要等待对方超时处理,放弃原SOCKET,重新开放连接。
如果我方作为SERVER对方设备作为CLIENT重启设备,同理,若我方不支持多CLIENT连接,也会形成无法连接问题

你可能感兴趣的:(stm32上实现TCP/IP通信的部分采坑心得)