STM32F104C8T6 + CH395Q 作为TCP服务器实现多TCP连接

发布时间 2023-07-12 15:15:25作者: 伽椰子真可爱
初始化 Socket 为 TCP 服务器模式
初始化步骤如下:
① 发送命令 CMD_SET_PROTO_TYPE_SN 设置 Socket 工作在 TCP 模式;
② 发送命令 CMD_SET_SOUR_PORT_SN 设置源端口 Sport;
③ 发送命令 CMD_OPEN_SOCKET_SN 打开 Socket;
④ 延时 2MS 以上发送命令 CMD_GET_CMD_STATUS 获取 CMD_OPEN_SOCKET_SN 执行状态,如果返回CH395_ERR_BUSY 表示 CH395 内部正在执行命令,需要再次执行④;如果返回 CH395_ERR_SUCCESS 表示命令执行成功,其他值表示打开 Socket 失败。
  在 TCP 服务器模式下,如果客户端进行连接,在 Socket 一直处于监听状态,不会产生超时中断,如果 TCP 连接成功,CH395 会产生 SINT_STAT_CONNECT 中断,此时单片机可以发送命令CMD_GET_REMOT_IPP_SN 来获取客户端的 IP 地址和端口号。
  默认的设置下,服务器多连接功能被关闭, TCP 服务端模式下,每个 Socket 只可以建立一个 TCP连接。
  在多连接模式使能的情况下,TCP 服务器可以连接多个 TCP 连接,单片机需要设置 Socket 的源端口和服务器的源端口一致,如果 TCP 服务器监听到连接,CH395 会查找当前所有的 Socket 的源端口是否和当前服务器一致,协议类型为 TCP,且处于被关闭状态,如果找到则立即将此 Socket 打开,将连接分配给此 Socket,并通知单片机有连接事件,如果没找到,则将连接复位。此模式下服务器的 Socket 仅用来监听,单片机需要分配其它 Socket 用于该服务器的连接。例如 Socket0 设置为服务器模式,Socket1 和 Socket2 用于此服务器的连接,步骤如下:
Socket0 执行①-④;
⑤ 向 Socket1 发送命令 CMD_SET_SOUR_PORT_SN 设置源端口 Sport;
⑥ 向 Socket1 发送命令 CMD_SET_PROTO_TYPE_SN 设置 Socket 工作在 TCP 模式;
⑦ 向 Socket2 发送命令 CMD_SET_SOUR_PORT_SN 设置源端口 Sport;
⑧ 向 Socket2 发送命令 CMD_SET_PROTO_TYPE_SN 设置 Socket 工作在 TCP 模式;
 
设置CH395Q为多连接模式的指令为:CMD40_SET_FUN_PARA
1 #define CMD40_SET_FUN_PARA                        0x55                          /* 设置功能参数 */

 调用函数void CH395SetStartPara(UINT32 mdata),将bit1设置为1即可;

 1 void AppMain(void *pdata)
 2 {
 3     uint8_t tPhy = 0;
 4 
 5     while(1)
 6     {
 7         while (1)
 8         {
 9               tPhy = CH395CMDGetPHYStatus();
10               iprintf("PHY Status = %d\r\n", tPhy);
11               if(tPhy == PHY_DISCONN)
12               {
13                  mDelaymS(200);
14               }
15               else
16               {
17                   iprintf("Network Connect Success\r\n");
18                   break;
19               }
20         }
21 
22         CH395SetStartPara(0x02);        //设置CH395进入多连接模式
23         LibInitSocketParam();
24         CH395SocketInitOpen(0);            //设置socket0,用于监听 socket1、2、3
25         CH395SocketInitOpenMultiple(1); //打开socket1、2、3
26 
27         while (1)
28         {
29             LibIwdgFeed();
30 
31             tPhy = CH395CMDGetPHYStatus();
32             if (tPhy == PHY_DISCONN)
33             {
34                 break;
35             }
36 
37             if (VarCalculationFlag == 0)
38             {
39                 if (CH395INTSTATUS == 0)
40                 {
41                     CH395GlobalInterrupt();
42                     FunSchedulingComputer();
43                 }
44             }
45         }
46     }
47 }
 1 /*******************************************************************************
 2 * Function Name  : CH395SetStartPara
 3 * Description    : 设置CH395启动参数
 4 * Input          : mdata
 5 * Output         : None
 6 * Return         : None
 7 *******************************************************************************/
 8 void CH395SetStartPara(UINT32 mdata)
 9 {
10     xWriteCH395Cmd(CMD40_SET_FUN_PARA);
11     xWriteCH395Data((UINT8)mdata);
12     xWriteCH395Data((UINT8)((UINT16)mdata>>8));
13     xWriteCH395Data((UINT8)(mdata >> 16));
14     xWriteCH395Data((UINT8)(mdata >> 24));
15 }
 1 /**********************************************************************************
 2 * Function Name  : CH395SocketInitOpen
 3 * Description    : 配置CH395 socket 参数,初始化并打开socket  多连接模式下设置
 4 * Input          : None
 5 * Output         : None
 6 * Return         : None
 7 **********************************************************************************/
 8 void CH395SocketInitOpenMultiple(UINT8 indexsocket)
 9 {
10     CH395SetSocketSourPort(indexsocket, Socket1SourPort);
11     CH395SetSocketProtType(indexsocket, PROTO_TYPE_TCP);
12 
13     CH395SetSocketSourPort(indexsocket + 1, Socket2SourPort);
14     CH395SetSocketProtType(indexsocket + 1, PROTO_TYPE_TCP);
15 
16     CH395SetSocketSourPort(indexsocket + 2, Socket3SourPort);
17     CH395SetSocketProtType(indexsocket + 2, PROTO_TYPE_TCP);
18 }
19 
20 /**********************************************************************************
21 * Function Name  : CH395SocketInitOpen
22 * Description    : 配置CH395 socket 参数,初始化并打开socket
23 * Input          : None
24 * Output         : None
25 * Return         : None
26 **********************************************************************************/
27 void CH395SocketInitOpen(UINT8 indexsocket)
28 {
29     UINT8 i = 0;
30 
31     /* socket 0为TCP模式 */
32     CH395SetSocketProtType(indexsocket, PROTO_TYPE_TCP);                /* socket 1 */
33     CH395SetSocketSourPort(indexsocket, SockInf.SourPort);              /* socket 1 */
34     i = CH395OpenSocket(indexsocket);                                   /* socket 1 */
35     mStopIfError(i);                                                    /*  */
36     i = CH395TCPListen (indexsocket);                                   /*  */
37     mStopIfError(i);                                                    /*检查是否成功*/
38 }