snibelyh 发表于 2021-4-10 15:03:06

分享Netxduo 监听多个客户端连接

项目需要用到tcp socket监听多个port,在外网的论坛上找到一个类似的,tcp创建多个socket监听同一个port,分享给有需要的坛友。
源链接:https://renesasrulz.com/synergy/f/synergy---forum/9717/how-to-connect-to-at-once-a-multiple-tcp-ip-client-connection
#include "tcp_thread.h"

#include "rtt/SEGGER_RTT.h"

#define APP_TCP_SOCKET_NUM      (3)
#define APP_TCP_PORT            (5000)
#define APP_TCP_INSTANT_ECHO    (1)
#define APP_TCP_RTT_LOG         (1)

static NX_TCP_SOCKET g_tcp_sck;

static ULONG g_not_listening = TX_FALSE;

static void g_tcp_sck_listen_cb(NX_TCP_SOCKET *, UINT);
static void g_tcp_sck_receive_cb(NX_TCP_SOCKET *);
static void g_tcp_sck_disconn_cb(NX_TCP_SOCKET *);

/* TCP Thread entry function */
void tcp_thread_entry(void)
{
    UINT status;

    /* Create all sockets */
    for (INT i = 0; i < APP_TCP_SOCKET_NUM; i++)
    {
      status = nx_tcp_socket_create(&g_ip, g_tcp_sck + i, "TCP Socket",
                                    NX_IP_NORMAL, NX_FRAGMENT_OKAY,
                                    NX_IP_TIME_TO_LIVE, 512, NX_NULL,
                                    g_tcp_sck_disconn_cb);
      if (NX_SUCCESS != status)
      {
            __BKPT(0);
      }
    }

#if APP_TCP_RTT_LOG
    SEGGER_RTT_printf(0, "Created %u TCP socket%s on port %lu\n",
                      APP_TCP_SOCKET_NUM, APP_TCP_SOCKET_NUM > 1 ? "s" : "",
                      APP_TCP_PORT);
#endif

    /* Start listening on the first socket */
    status = nx_tcp_server_socket_listen(&g_ip, APP_TCP_PORT, g_tcp_sck, 0,
                                       g_tcp_sck_listen_cb);
    if (NX_SUCCESS != status)
    {
      __BKPT(0);
    }

    while (1)
    {
#if APP_TCP_INSTANT_ECHO
      /* Everything else is handled from TCP callbacks dispatched from
         * IP instance thread */
      tx_thread_suspend(tx_thread_identify());
#else
      /* Receive pointers to TCP socket and network packet from
         * TCP callback */
      ULONG msg;
      status = tx_queue_receive(&g_tcp_q, msg, TX_WAIT_FOREVER);

      if (TX_SUCCESS == status)
      {
            NX_TCP_SOCKET * p_sck    = (NX_TCP_SOCKET *) msg;
            NX_PACKET   * p_packet = (NX_PACKET *)   msg;

            status = nx_tcp_socket_send(p_sck, p_packet, NX_NO_WAIT);
            if (NX_SUCCESS != status)
            {
                nx_packet_release(p_packet);
            }
      }

      else
      {
            /* Unrecoverable error */
            tx_thread_suspend(tx_thread_identify());
      }
#endif
    }
}


static void g_tcp_sck_listen_cb(NX_TCP_SOCKET * p_sck, UINT port)
{
    /* Incoming connection, accept and queueing new requests */
    nx_tcp_server_socket_accept(p_sck, NX_NO_WAIT);
    nx_tcp_server_socket_unlisten(&g_ip, port);
    nx_tcp_socket_receive_notify(p_sck, g_tcp_sck_receive_cb);

#if APP_TCP_RTT_LOG
    ULONG ip, client_port;
    nx_tcp_socket_peer_info_get(p_sck, &ip, &client_port);
    SEGGER_RTT_printf(0, " Incoming connection from %lu.%lu.%lu.%lu:%lu\n",
                      p_sck, (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
                      (ip >> 8) & 0xFF, (ip) & 0xFF, client_port);
#endif

    /* Attempt to find another idle socket to start listening on */
    ULONG state = 0;

    for (INT i = 0; i < APP_TCP_SOCKET_NUM; i++)
    {
      /* Get socket state value */
      nx_tcp_socket_info_get(g_tcp_sck + i,
                               0, 0, 0, 0, 0, 0, 0, &state, 0, 0, 0);

      /* Start lisnening if socket is idle */
      if (NX_TCP_CLOSED == state)
      {
            nx_tcp_server_socket_listen(&g_ip, port, g_tcp_sck + i, 0,
                                        g_tcp_sck_listen_cb);

            break;
      }
    }

    /* Ran out of sockets, set appropriate flag to let next socket to
   * disconnect know that it should start listening right away. */
    if (NX_TCP_CLOSED != state)
    {
      g_not_listening = TX_TRUE;
    }
}


static void g_tcp_sck_receive_cb(NX_TCP_SOCKET * p_sck)
{
    NX_PACKET * p_packet;

    /* This callback is invoked when data is already received. Retrieving
   * packet with no suspension. */
    nx_tcp_socket_receive(p_sck, &p_packet, NX_NO_WAIT);

#if APP_TCP_RTT_LOG
    ULONG ip, client_port;
    nx_tcp_socket_peer_info_get(p_sck, &ip, &client_port);
    SEGGER_RTT_printf(0, " Incoming packet (%lu bytes) from %lu.%lu.%lu.%lu:%lu\n",
                      p_sck, p_packet->nx_packet_length, (ip >> 24) & 0xFF,
                      (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, (ip) & 0xFF, client_port);
#endif

#if APP_TCP_INSTANT_ECHO
    /* Send packet back on the same TCP socket */
    nx_tcp_socket_send(p_sck, p_packet, NX_NO_WAIT);
#else
    ULONG msg =
    {
      (ULONG) p_sck, (ULONG) p_packet
    };

    /* Sent TCP socket and packet pointers to user thread */
    if (TX_SUCCESS != tx_queue_send(&g_tcp_q, msg, TX_NO_WAIT))
    {
      nx_packet_release(p_packet);
    }
#endif
}


static void g_tcp_sck_disconn_cb(NX_TCP_SOCKET * p_sck)
{
#if APP_TCP_RTT_LOG
    SEGGER_RTT_printf(0, " Client disconnected\n", p_sck);
#endif

    nx_tcp_server_socket_unaccept(p_sck);

    /* If all sockets are busy, start listening again */
    if (TX_TRUE == g_not_listening)
    {
      nx_tcp_server_socket_listen(&g_ip, APP_TCP_PORT, p_sck, 0,
                                    g_tcp_sck_listen_cb);

      g_not_listening = TX_FALSE;
    }
}



eric2013 发表于 2021-4-10 15:36:15

谢谢分享
页: [1]
查看完整版本: 分享Netxduo 监听多个客户端连接