lwip tcp同一端口支持多个连接

lwip对于同一端口支持多个连接,只需在上位机进行连接时,即accept 能连接到即可,直接上代码:

#ifndef _SOCKET_APP_H
#define _SOCKET_APP_H


#include "global_includes.h"


#define INVALID_SOCKET -1


void socket_app_init(void);
void socket_app_pool(void);
bool socket_upload_txdata(uint8* buf, uint16 len);


#endif
#include "socket_app.h"
#include "sys_info.h"
#include "user_info.h"
#include "sys_timer.h"
#include "rtx_data_analy.h"
#include "hmi_app_pool.h"
#include "lwip/sockets.h"

#if UDP_MULTSERVER
#include "mult_app.h"
#endif

static struct sys_data_info* net_sys_info = NULL;

#define TCP_SPLICE_ENABLE  0

#define TCP_MAX_CONNECTION        2  // 2  UDP_MULTSERVER
#define TCP_UNVALID_FD            -1

#define NET_TXBUF_SIZE         1500
#define NET_RXBUF_SIZE         1500


uint8 net_rxbuf[NET_RXBUF_SIZE];
uint8 net_txbuf[NET_TXBUF_SIZE];

struct sockaddr_in  tcp_local_addr;
struct sockaddr_in  local_addr;
struct sockaddr_in remote_addr_temp;

enum
{
  TCP_STATE_IDLE = 0,
  TCP_STATE_HEAD,
  TCP_STATE_DATA,
  TCP_STATE_ANALYDATA,
};

#define NET_TCP_RXBUFSIZE 1500
#define NET_TCP_TXBUFSIZE 1500
#define NET_TCP_HEADLEN   4
uint8 net_tcp_rxbuf[NET_TCP_RXBUFSIZE];
uint16 net_tcp_lenoffset;
uint16 net_tcp_rxitem = 0;
uint16 net_tcp_packetlen = 0;
uint8  net_tcp_state  = 0;

#define TCP_CLOSE(len,tcp_sockfd)            {if(len<=0){close(tcp_sockfd);tcp_sockfd = TCP_UNVALID_FD;net_sys_info->debug_view_info->tcpupenable = false;}}

#if UDP_MULTSERVER
static int32 udp_multsockfd[UDP_MULTSERVER];

/****************************************************************************************
*函数名称: net_udpmult_init
*
*函数说明: 多UDP端口初始化
****************************************************************************************/
void net_udpmult_init(void)
{
  uint8 i;

  uint8  optval = 1;

  for(i = 0; i < UDP_MULTSERVER; i++)
  {
    udp_multsockfd[i]    =   -1;
    while(1)
    {
      rt_thread_delay(RT_TICK_PER_SECOND / 20);
      memset(&local_addr, 0, sizeof(struct sockaddr_in));

      local_addr.sin_family       = AF_INET;
      local_addr.sin_port         = htons(NET_PORT + i);//本地端口

      local_addr.sin_addr.s_addr  = INADDR_ANY;
      udp_multsockfd[i]                = socket(AF_INET, SOCK_DGRAM, 0);
      if(udp_multsockfd[i] <= 0)
      {
        continue;
      }
      setsockopt(udp_multsockfd[i], SOL_SOCKET, SO_BROADCAST, (void*)&optval, sizeof(optval));

      if(bind(udp_multsockfd[i], (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0)
      {
        continue;
      }
      break;
    }
  }
}

void net_udpmult_pool(void)
{
  uint8 i;
  uint32 len = 0;;
  int rxlen  = 0;
  int txlen  = 0;
  int16 ret;
  fd_set readset;
  fd_set writeset;
  struct timeval tv;

  len = sizeof(struct sockaddr_in);

  for(i = 0; i < UDP_MULTSERVER; i++)
  {
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&readset);
    FD_ZERO(&writeset);

    FD_SET(udp_multsockfd[i], &readset);
    FD_SET(udp_multsockfd[i], &writeset);

    ret = select(udp_multsockfd[i] + 1, &readset, 0, 0, &tv);
    if(ret > 0)  //说明有就绪的文件描述符
    {
      if(FD_ISSET(udp_multsockfd[i], &readset))  //判断是否为读取的文件描述符集
      {
        rxlen = recvfrom(udp_multsockfd[i], net_rxbuf, NET_RXBUF_SIZE, 0, (struct sockaddr*)&remote_addr_temp, (socklen_t*)&len);  //接收数据

        if(rxlen)
        {
          if(lwip_recvbroad() !=  0)
          {
            remote_addr_temp.sin_addr.s_addr   =       INADDR_BROADCAST;
          }
          net_sys_info->debug_view_info->sockfd = udp_multsockfd[i];
          net_sys_info->debug_view_info->remote_udp_sockaddr  = remote_addr_temp;
          net_sys_info->debug_view_info->trans_type = TRANS_TYPE_UDP;

          txlen = net_rxdata_analy(net_rxbuf, rxlen, net_txbuf, NET_TXBUF_SIZE, EXTERNAL);
          if(txlen)
          {
            txlen = sendto(udp_multsockfd[i], net_txbuf, txlen, 0, (struct sockaddr*)&remote_addr_temp, sizeof(struct sockaddr_in));
            hmi_busy_set(HMI_IO_BUSY);
            if(txlen)
            {
              net_sys_info->temp_information->trans_count++;
            }
          }
          else
          {
#if !SYS_BOOT_DEVICE
            mult_write(net_rxbuf, rxlen, (NET_PORT + i), udp_multsockfd[i], &remote_addr_temp);
#endif
          }
        }
      }
    }
  }
}

#endif

#if TCP_SERVER

#define ACCEPT_SOCK_MAX    8
int tcp_listenfd[TCP_MAX_CONNECTION];
int tcp_connectfd[TCP_MAX_CONNECTION][ACCEPT_SOCK_MAX];
static int32       tcp_sockfd = -1;
/****************************************************************************************
*函数名称: net_tcp_pool
*
*函数说明: 网络tcp数据包处理函数
****************************************************************************************/
const int i32NetPort[TCP_MAX_CONNECTION] =
{
  7000,
  502
};

void net_tcp_init(void)
{
  uint8 i;
  uint8 j;

  for(i = 0; i < TCP_MAX_CONNECTION; i++)
  {
    for(j = 0; j < ACCEPT_SOCK_MAX; j++)
    {
      tcp_connectfd[i][j] = TCP_UNVALID_FD;
    }


    while(1)
    {
      rt_thread_delay(RT_TICK_PER_SECOND / 20);

      tcp_local_addr.sin_family = AF_INET;
      tcp_local_addr.sin_port = htons(i32NetPort[i]);
      tcp_local_addr.sin_len = sizeof(tcp_local_addr);
      tcp_local_addr.sin_addr.s_addr = INADDR_ANY;

      tcp_listenfd[i] = socket(AF_INET, SOCK_STREAM, 0);
      if(tcp_listenfd[i] <= 0)
      {
        continue;
      }

      if(bind(tcp_listenfd[i], (struct sockaddr*) &tcp_local_addr, sizeof(tcp_local_addr)) < 0)
      {
        continue ;
      }
      if(listen(tcp_listenfd[i], TCP_MAX_CONNECTION) < 0)
      {
        continue;
      }
      break;
    }
  }
}

/****************************************************************************************
*函数名称: net_tcp_pool
*
*函数说明: 网络tcp数据包处理函数
****************************************************************************************/
#if 0
void net_tcp_pool(void)
{
  static uint32 len = 0;;
  static int rxlen  = 0;
  static int txlen  = 0;
  static int16 ret;
  static uint8 i;
  static fd_set readset;
  static fd_set writeset;

  struct timeval tv;
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  len = sizeof(struct sockaddr_in);

  for(i = 0; i < TCP_MAX_CONNECTION; i++)
  {
    rxlen = 0;
    FD_ZERO(&readset);
    FD_ZERO(&writeset);
    FD_SET(tcp_listenfd[i], &readset);
    FD_SET(tcp_listenfd[i], &writeset);
    ret = select(tcp_listenfd[i] + 1, &readset, &writeset, 0, &tv);
    if(ret  > 0)
    {
      if(FD_ISSET(tcp_listenfd[i], &readset))
      {
        tcp_sockfd = accept(tcp_listenfd[i], (struct sockaddr*)&remote_addr_temp, (socklen_t*)&len);
        if(tcp_sockfd > 0)
        {
//          if(tcp_connectfd[i]  !=  INVALID_SOCKET)
//          {
//            close(tcp_connectfd[i]);
//            tcp_connectfd[i] = INVALID_SOCKET;
//          }
          tcp_connectfd[i] = tcp_sockfd;
          net_sys_info->debug_view_info->tcp_sockfd = tcp_connectfd[i];
          net_sys_info->debug_view_info->sockfd     = tcp_connectfd[i];
          net_tcp_state                         = TCP_STATE_IDLE;

          int flag = 1;
          /* set option at TCP level */ /* name of option */ /* the cast is historical cruft */ /* length of option value */
          ret = setsockopt(tcp_sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &flag,                     sizeof(int));

        }
      }
    }
    if(tcp_connectfd[i]  !=  TCP_UNVALID_FD)
    {
      FD_ZERO(&readset);
      FD_ZERO(&writeset);
      FD_SET(tcp_connectfd[i], &readset);
      FD_SET(tcp_connectfd[i], &writeset);
      ret = select(tcp_connectfd[i] + 1, &readset, &writeset, 0, &tv);
      if(ret  > 0)
      {
        if(FD_ISSET(tcp_connectfd[i], &readset)  && FD_ISSET(tcp_connectfd[i], &writeset))
        {
          rxlen = recv(tcp_connectfd[i], net_rxbuf, NET_RXBUF_SIZE, 0);
          if(rxlen <= 0)
          {
            close(tcp_connectfd[i]);
            tcp_connectfd[i] = TCP_UNVALID_FD;
            net_sys_info->debug_view_info->sockfd = TCP_UNVALID_FD;
            net_sys_info->debug_view_info->tcp_sockfd = TCP_UNVALID_FD;
          }
          else
          {
            txlen = net_rxdata_analy(net_rxbuf, rxlen, net_txbuf, NET_TXBUF_SIZE, EXTERNAL);
            if(txlen)
            {
              txlen = send(tcp_connectfd[i], net_txbuf, txlen, 0);
              hmi_busy_set(HMI_IO_BUSY);

              TCP_CLOSE(txlen, tcp_connectfd[i]);
            }
            hmi_busy_set(HMI_IO_BUSY);
          }
        }
      }
    }
  }
}
#else
void net_tcp_pool(void)
{
  static uint32 len = 0;;
  static int rxlen  = 0;
  static int txlen  = 0;
  static int16 ret;
  static uint8 i;
  static uint8 j;
  static fd_set readset;
  static fd_set writeset;
  static uint8 byport_ix = 0;

  struct timeval tv;
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  len = sizeof(struct sockaddr_in);

  for(i = 0; i < TCP_MAX_CONNECTION; i++)
  {
    rxlen = 0;
    FD_ZERO(&readset);
    FD_ZERO(&writeset);
    FD_SET(tcp_listenfd[i], &readset);
    FD_SET(tcp_listenfd[i], &writeset);
    ret = select(tcp_listenfd[i] + 1, &readset, &writeset, 0, &tv);
    if(ret  > 0)
    {
      if(FD_ISSET(tcp_listenfd[i], &readset))
      {
        tcp_sockfd = accept(tcp_listenfd[i], (struct sockaddr*)&remote_addr_temp, (socklen_t*)&len);
        if(tcp_sockfd > 0)
        {
          // if(tcp_connectfd[i]  !=  INVALID_SOCKET)
          // {
          //   close(tcp_connectfd[i]);
          //   tcp_connectfd[i] = INVALID_SOCKET;
          // }
          for(j = 0; j < ACCEPT_SOCK_MAX; j++)
          {
            if(tcp_connectfd[i][j]  ==  INVALID_SOCKET)
            {
              break;
            }
          }
          // j = (j == ACCEPT_SOCK_MAX) ? 0 : j;
          if(j == ACCEPT_SOCK_MAX)
          {
            j = byport_ix;
            byport_ix = (byport_ix + 1) % ACCEPT_SOCK_MAX;
          }
          if(tcp_connectfd[i][j]  !=  INVALID_SOCKET)
          {
            close(tcp_connectfd[i][j]);
            tcp_connectfd[i][j] = INVALID_SOCKET;
          }
          tcp_connectfd[i][j] = tcp_sockfd;
          net_sys_info->debug_view_info->tcp_sockfd = tcp_connectfd[i][j];
          net_sys_info->debug_view_info->sockfd     = tcp_connectfd[i][j];
          net_tcp_state                         = TCP_STATE_IDLE;

          int flag = 1;
          /* set option at TCP level */ /* name of option */ /* the cast is historical cruft */ /* length of option value */
          ret = setsockopt(tcp_sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &flag,                     sizeof(int));

        }
      }
    }
    for(j = 0; j < ACCEPT_SOCK_MAX; j++)
    {
      if(tcp_connectfd[i][j]  !=  TCP_UNVALID_FD)
      {
        FD_ZERO(&readset);
        FD_ZERO(&writeset);
        FD_SET(tcp_connectfd[i][j], &readset);
        FD_SET(tcp_connectfd[i][j], &writeset);
        ret = select(tcp_connectfd[i][j] + 1, &readset, &writeset, 0, &tv);
        if(ret  > 0)
        {
          if(FD_ISSET(tcp_connectfd[i][j], &readset)  && FD_ISSET(tcp_connectfd[i][j], &writeset))
          {
            rxlen = recv(tcp_connectfd[i][j], net_rxbuf, NET_RXBUF_SIZE, 0);
            if(rxlen <= 0)
            {
              close(tcp_connectfd[i][j]);
              tcp_connectfd[i][j] = TCP_UNVALID_FD;
              net_sys_info->debug_view_info->sockfd = TCP_UNVALID_FD;
              net_sys_info->debug_view_info->tcp_sockfd = TCP_UNVALID_FD;
            }
            else
            {
              txlen = net_rxdata_analy(net_rxbuf, rxlen, net_txbuf, NET_TXBUF_SIZE, EXTERNAL);
              if(txlen)
              {
                txlen = send(tcp_connectfd[i][j], net_txbuf, txlen, 0);
                hmi_busy_set(HMI_IO_BUSY);

                TCP_CLOSE(txlen, tcp_connectfd[i][j]);
              }
              hmi_busy_set(HMI_IO_BUSY);
            }
          }
        }
      }
    }

  }
}
#endif
#endif

/****************************************************************************************
*函数名称: socket_app_init
*
*函数说明: socket 应用初始化函数
****************************************************************************************/
void socket_app_init(void)
{
  net_sys_info  = sys_info_datainfoget();
#if TCP_SERVER
  net_tcp_init();
#endif

#if UDP_MULTSERVER
  net_udpmult_init();
#endif

}

/****************************************************************************************
*函数名称: socket_app_pool
*
*函数说明: 网络socket数据包处理函数
****************************************************************************************/
void socket_app_pool(void)
{
#if TCP_SERVER
  net_tcp_pool();
#endif
#if UDP_MULTSERVER
  net_udpmult_pool();
#endif
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大文梅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值