海思3559万能平台搭建:TCP客户端网口编程

简介: 海思3559万能平台搭建:TCP客户端网口编程

前言

 日常开发除了串口还有网口也用来作为常用的协议收发端口,补充常见的网口编程

基本概念

 该博客写的比较清晰了

https://www.cnblogs.com/luoxiao23/p/11545363.html#:~:text=Linux%E4%B8%AD%E7%9A%84%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E9%80%9A%E8%BF%87Socket%20%28%E5%A5%97%E6%8E%A5%E5%AD%97%29%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0%EF%BC%8CSocket%E6%98%AF%E4%B8%80%E7%A7%8D%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E3%80%82,%E6%B5%81%E5%BC%8F%E7%9A%84%E5%A5%97%E6%8E%A5%E5%AD%97%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BE%9B%E5%8F%AF%E9%9D%A0%E7%9A%84%E3%80%81%E9%9D%A2%E5%90%91%E8%BF%9E%E6%8E%A5%E7%9A%84%E9%80%9A%E8%AE%AF%E6%B5%81%E3%80%82%20%E5%AE%83%E4%BD%BF%E7%94%A8%E4%BA%86TCP%E5%8D%8F%E8%AE%AE%E3%80%82%20TCP%E4%BF%9D%E8%AF%81%E4%BA%86%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93%E7%9A%84%E6%AD%A3%E7%A1%AE%E6%80%A7%E5%92%8C%E9%A1%BA%E5%BA%8F%E6%80%A7%E3%80%82

代码

tcp client写法:

#include "eth.h"
#define SERVER_PORT  8080    //
#define SERVER_IP  "192.168.119.100"  //服务器IP地址
int listen_fd = -1;
void signal_handler(int arg)
{
  printf("close listen_fd(signal = %d)\n", arg);
  close(listen_fd);
  exit(0);
}
 /*描述  :网口发送线程
 *参数  :arg 无参数传入
 *返回值:无
 *注意  :使用需打开网口服务器端
 */
HI_VOID * eth_client_send_task(HI_VOID *arg)
{
  int connect_fd = -1;
  struct sockaddr_in server;
  socklen_t saddrlen = sizeof(server);
  memset(&server, 0, sizeof(server));
  connect_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (connect_fd < 0)
  {
  printf("socket error!\n");
  // return NULL;
  }
    printf("\nETH CLIENT SEND TEST\n");
  server.sin_family = AF_INET;
  server.sin_port = htons(SERVER_PORT);
  server.sin_addr.s_addr = inet_addr(SERVER_IP);
  if (connect(connect_fd, (struct sockaddr *)&server, saddrlen) < 0)
  {
  printf("connect failed!\n");
  // return -1;
  }
  char sendbuf[1024]="HelloWorld1234567890";
  while (1)
  {
        sleep(1);
  write(connect_fd, sendbuf, sizeof(sendbuf));
  }
  close(connect_fd);
  return 0;
}
/*描述  :网口接收线程
 *参数  :arg 无参数传入
 *返回值:无
 *注意  :使用需打开网口服务器端
 */
HI_VOID * eth_client_recv_task(HI_VOID *arg)
{
  cpu_set_t mask;//cpu核的集合
    cpu_set_t get;//获取在集合中的cpu
    int num = sysconf(_SC_NPROCESSORS_CONF);
    printf("frame_check_task:system has %d processor(s)\n", num);
    CPU_ZERO(&mask);//置空
    CPU_SET(0, &mask);//设置亲和力值
    if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)//设置线程CPU亲和力
    {
        fprintf(stderr, "set thread affinity failed\n");
    }
    if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0)//获取线程CPU亲和力
    {
        fprintf(stderr, "get thread affinity failed\n");
    }
  int connect_fd = -1;
    int recv_len,i;
  struct sockaddr_in server;
  socklen_t saddrlen = sizeof(server);
  uint8 data_header[] = {0x55, 0xAA};
  unsigned char addchk=0;
  // uint8 data_header[] = {0x55, 0xAA};
  // printf("\nbeforen DataParser\n ");
  DataParser *data_parser = parser_init(data_header, sizeof(data_header), NULL, 0, CMD_LENGTH);
  // printf("\nDataParser INIT SUCCESS\n ");
  char* tmp_cmd=(char*)&g_trk_cmd;
  memset(&server, 0, sizeof(server));
  connect_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (connect_fd < 0)
  {
  printf("socket error!\n");
  // return NULL;
  }
    printf("\nETH CLIENT RECV TEST\n");
  server.sin_family = AF_INET;
  server.sin_port = htons(SERVER_PORT);
  // server.sin_addr.s_addr = inet_addr(SERVER_IP);
  server.sin_addr.s_addr = inet_addr(server_ip);
  if (connect(connect_fd, (struct sockaddr *)&server, saddrlen) < 0)
  {
  printf("connect failed!\n");
  // return -1;
  }
  // char PLATFORM_IP_SET[64]={0};
  // char PLATFORM_IP_CMD[]="192.168.0.168";
  // sprintf(PLATFORM_IP_SET,"ifconfig eth0 %s up",PLATFORM_IP_CMD);
  // system(PLATFORM_IP_SET);
  else
  {
  char recvbuf[1024]={0};
  while (1)
  {
    recv_len = read(connect_fd, recvbuf, sizeof(recvbuf));
    if(recv_len)
    {
    // printf("\nEth:recv origin data: ");
    // recvbuf[len] = '\0';  
    for (i = 0;i < recv_len ;i++)
    {
      // printf("%02x  ",recvbuf[i]);  
      if(parser_put_data(data_parser, recvbuf[i]) == RESULT_TRUE)
      {
      // printf("成功解析出一帧数据...\n");
      // /* 一位一位取出解析后的数据 */
      // g_trk_cmd.length  = parser_get_data(data_parser, 0);
      // g_trk_cmd.CmdType = parser_get_data(data_parser, 1);
      // for (int ii = 0; ii < DATA_LENGTH ;ii++)
      // {
      //  g_trk_cmd.Para[ii] = parser_get_data(data_parser, 2+ii);
      // }
      tmp_cmd=(char*)&g_trk_cmd;
      // memset_s(tmp_cmd, sizeof(g_trk_cmd)-sizeof(data_header), 0, sizeof(g_trk_cmd)-sizeof(data_header));
      addchk = 0;
      for(int jj=0;jj<sizeof(g_trk_cmd)-sizeof(data_header);jj++)
      {
        tmp_cmd[jj+2]=parser_get_data(data_parser, jj);
        printf("%x ",tmp_cmd[jj+2]);
      }
      printf("\n");
      for(int kk = 2;kk < sizeof(g_trk_cmd)-1;kk++)
      {
        // addchk += parser_get_data(data_parser, kk);
        addchk+=tmp_cmd[kk];
        printf("%x ",tmp_cmd[kk]);
      }
      printf("\n");
      printf("addchk is %x\n",addchk);
      g_trk_cmd.addchk = parser_get_data(data_parser,(CMD_LENGTH-1-2));//第19个数,从0开始计18,故-1,又因为去头在-2
      printf("g_trk_cmd.addchk is %x\n",g_trk_cmd.addchk);
      if(addchk != g_trk_cmd.addchk )
      {
        memset_s(((uint8_t*)&g_trk_cmd)+2,
        sizeof(g_trk_cmd)-sizeof(data_header),
        0,
        sizeof(g_trk_cmd)-sizeof(data_header));
        continue;
      }
      g_trk_cmd.length  = tmp_cmd[2];
      printf(" tmp_cmd[2]is %x\n",tmp_cmd[2]);
      g_trk_cmd.CmdType = tmp_cmd[3];
      printf(" tmp_cmd[3]is %x\n",tmp_cmd[3]);
      for (int ii = 0; ii < DATA_LENGTH ;ii++)
      {
        g_trk_cmd.Para[ii] = tmp_cmd[ii+4];;
      }
      // printf("数据长度是0x%x\n", parser_get_data(data_parser, 0));
      // printf("功能码是0x%x\n", parser_get_data(data_parser, 1));
      // printf("具体功能是0x%x\n\n\n", parser_get_data(data_parser, 2));
      }
    }
    // printf("\n"); 
    }
    protocol_parser();
  }
  close(connect_fd);
  }
  return 0;
}

头文件

/************************************************************************************************
*****Describe: This program is writen to operate HI35xx eth devices.                     *****
*****Author: xin.han                        *****
*****Date: 2022-09-17                  *****
*************************************************************************************************/
#ifndef _ETH_H_
#define _ETH_H_
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "platform.h"
#include "parser.h"
#include "queue.h"
/*描述  :网口发送线程
 *参数  :arg 无参数传入
 *返回值:无
 *注意  :使用需打开网口服务器端
 */
HI_VOID * eth_client_send_task(HI_VOID *arg);
HI_VOID * eth_client_recv_task(HI_VOID *arg);
HI_VOID * eth_server_task(HI_VOID *arg);
#endif

 还是新建收发线程,用网口助手进行模拟调试

/*描述 :网口接收线程

*参数 :arg 无参数传入

*返回值:无

*注意 :使用需打开网口服务器端

*/

 tcp服务器端代码和udp的代码详见

https://blog.csdn.net/Mr_XJC/article/details/106788694

https://blog.csdn.net/YEDITABA/article/details/54635543

小bug

 单纯的这样测试,在通路都正常的情况下,短时间是没有测出来问题的

 但是有次忘记打开服务器端后,就会发现程序闪退了!

 远程调试一下发现

J
:k[i].[i].F575859// {// else
ate :...  60  char sendbuf[1024]="HelloWorld1234567890";  
while (1) 
sleep(1); 
write(connect fd, sendbuf, sizeof(sendbuf));  
出现异常。 x Broken pipe
close(connect fd);  
// }  

 broken pipe最直接的意思是:写入端出现的时候,另一端却休息或退出了,因此造成没有及时取走管道中的数据,从而系统异常退出

 那就很明显了,加个判断在链接成功的时候在执行收发操作

 以后写代码还是得严谨,最基本的ifelse不能老是偷懒只写一半,不然真的可能积累不少没必要的错误经验


相关文章
|
网络协议 Java
Java BIO tcp服务端向客户端消息群发代码教程实战
java BIO tcp服务端向客户端消息群发代码教程实战
161 0
Java BIO tcp服务端向客户端消息群发代码教程实战
|
缓存 网络协议 Java
在项目中使用Curator的Java 客户端搭建后进行长TCP连接和TCP权限配置【Zookeeper】
在项目中使用Curator的Java 客户端搭建后进行长TCP连接和TCP权限配置【Zookeeper】
291 0
在项目中使用Curator的Java 客户端搭建后进行长TCP连接和TCP权限配置【Zookeeper】
|
网络协议 Linux 网络性能优化
Linux网络原理及编程(6)——第十六节 TCP可靠性保证的原理
你在应用层上想要发送一个信息,但是我在底层可能是通过发送多次、甚至有触发了超时重传等等。而站在用户的角度呢,你不用去管它,我传输层不管怎么发,反正最终把你的数据发出去就可以了。也就是说,应用层的传输和底层传输层的并不是一对一、一一对应的关系。
174 0
Linux网络原理及编程(6)——第十六节 TCP可靠性保证的原理
|
网络协议 安全 Linux
Linux网络原理及编程(5)——第十五节 TCP的连接(三次握手、四次挥手)
本节我们来介绍TCP连接的建立和断开。我们主要介绍两个过程、两个状态。
203 0
Linux网络原理及编程(5)——第十五节 TCP的连接(三次握手、四次挥手)
|
存储 网络协议 算法
|
网络协议 安全 网络架构
Tcp 客户端 | 学习笔记
快速学习 Tcp 客户端
Tcp 客户端 | 学习笔记
|
网络协议 安全 测试技术
TCP 编程快速入门案例分析 | 学习笔记
快速学习 TCP 编程快速入门案例分析
TCP 编程快速入门案例分析 | 学习笔记
|
域名解析 网络协议 Unix
TCP 编程-服务器监听 | 学习笔记
快速学习 TCP 编程-服务器监听
TCP 编程-服务器监听 | 学习笔记
|
网络协议 C++
C++网络通信实例(TCP/IP协议,包括服务端与客户端通信)
C++网络通信实例(TCP/IP协议,包括服务端与客户端通信)
505 0
C++网络通信实例(TCP/IP协议,包括服务端与客户端通信)
|
网络协议
TCP编程中的客户端与服务端的通信实现
TCP编程中的客户端与服务端的通信实现
132 0