comtcp简介

comtcp程序实现linux平台下串口网口数据转发功能,将串口与网口数据透明转发,应用该程序可以用网络TCP访问串口设备;

#include#include#include#include#include      /*文件控制定义*/#include    /*PPSIX终端控制定义*/#include#include#include #include#include#include#include#include#include /* epoll function */#include#defineMAXEPOLLSIZE 5//表示MAXEPOLLSIZE-1个#defineMAXLINE 256#defineMAXEVENTS 10#define FALSE 0#define TRUE  1struct sPrivateReg{int fd;unsigned int lastaccesstime;}__attribute__((packed));int connfd,fcom,comindex,tcpindex;pthread_mutex_t rs485busdata_mut; unsigned char volatile rs485busyflag;void set_speed(int fd,int speed){struct termios   Opt;tcgetattr(fd, &Opt);cfsetispeed(&Opt, speed);cfsetospeed(&Opt, speed);tcsetattr(fd, TCSANOW, &Opt);}int set_Parity(int fd,int databits,int stopbits,int parity){struct termios options;if  ( tcgetattr( fd,&options)  !=  0){perror("SetupSerial 1");return(FALSE);}options.c_iflag &= ~IXOFF;options.c_iflag &= ~IXON;options.c_cflag &= ~CSIZE;switch (databits) /*设置数据位数*/{case 7:options.c_cflag |= CS7;break;case 8:options.c_cflag |= CS8;break;default:printf("Unsupported data size");return (FALSE);}switch (parity){case 'n':case 'N':options.c_cflag &= ~PARENB;   /* Clear parity enable */options.c_iflag &= ~INPCK;     /* Enable parity checking */break;case 'o':case 'O':options.c_cflag |= (PARODD | PARENB);  /* 设置为奇效验*/options.c_iflag |= INPCK;             /* Disnable parity checking */break;case 'e':case 'E':options.c_cflag |= PARENB;     /* Enable parity */options.c_cflag &= ~PARODD;   /* 转换为偶效验*/options.c_iflag |= INPCK;       /* Disnable parity checking */break;case 'S':case 's':  /*as no parity*/options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;break;default:printf("Unsupported parity");return (FALSE);}/* 设置停止位*/switch (stopbits){case 1:options.c_cflag &= ~CSTOPB;break;case 2:options.c_cflag |= CSTOPB;break;default:printf("Unsupported stop bits");return (FALSE);}/* Set input parity option */if (parity != 'n')options.c_iflag |= INPCK;tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */options.c_cc[VTIME] = 1; //100msoptions.c_cc[VMIN] = 255;options.c_iflag &= ~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IXANY);options.c_oflag &= ~OPOST;options.c_lflag &= ~(ECHO|ECHONL|ISIG|IEXTEN|ICANON);if (tcsetattr(fd,TCSANOW,&options) != 0){perror("SetupSerial 3");return (FALSE);}return (TRUE);}int OpenDev(char *Dev){int fd = open( Dev, O_RDWR );         //| O_NOCTTY | O_NDELAYif (-1 == fd){/*设置数据位数*/perror("Can't Open Serial Port");return -1;}elsereturn fd;}void Uart_set_send(int fd){int status;ioctl(fd, TIOCMGET, &status);status &= ~TIOCM_RTS;ioctl(fd, TIOCMSET, &status);}void Uart_set_get(int fd){int status;ioctl(fd, TIOCMGET, &status);status |= TIOCM_RTS;ioctl(fd, TIOCMSET, &status);}void Chekbusy(int fd) {int status;ioctl(fd, TIOCSERGETLSR, &status);while(((status&0x0001)==0)){ioctl(fd, TIOCSERGETLSR, &status);}usleep(20);Uart_set_get(fd); }void Uart_send(int fd,char *data ,int longer){int nread;Uart_set_send(fd); nread = write(fd, data ,longer);Chekbusy(fd);}int Uart_read(int fd,unsigned char *rcv_buf,int num,int sec,int usec){int retval;fd_set rfds;struct timeval tv;int ret=-1;tv.tv_sec = sec;//set the rcv wait timetv.tv_usec = usec;//100000us = 0.1swhile(1){FD_ZERO(&rfds);FD_SET(fd,&rfds);retval = select(fd+1,&rfds,NULL,NULL,&tv);if(retval ==-1){perror("select()");break;}else if(retval){ret= read(fd,rcv_buf,num);}else{break;}}return ret;  }void DoComEvent(int *index){int  rwnum;unsigned char RTU_RXBuf[255];while(1){rwnum=Uart_read(fcom,RTU_RXBuf,255,0,500000);if(rwnum>0){send(connfd,RTU_RXBuf , rwnum, 0);rs485busyflag=0;}usleep(1000);}}int setnonblocking(int sockfd){if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {return -1;}return 0;}int getavailablefd(unsigned int nowdatetime,struct sPrivateReg Private_Reg_Buf[]){unsigned int oversecmax = 0;int ret = -1;int i;for(i = 0; i< MAXEPOLLSIZE; i++){if(Private_Reg_Buf[i].fd == -1)return i;else if(oversecmax60){printf("close_fd(overtime): %d", Private_Reg_Buf[ret].fd);Private_Reg_Buf[ret].fd = -1;shutdown(Private_Reg_Buf[ret].fd, SHUT_RDWR);close(Private_Reg_Buf[ret].fd);}elseret = -1;return ret;}struct sPrivateReg * findfd(int fd,struct sPrivateReg Private_Reg_Buf[]){int i;for(i = 0; i< MAXEPOLLSIZE; i++)if(Private_Reg_Buf[i].fd == fd)return &Private_Reg_Buf[i];return NULL;}unsigned int gettickcount(){struct sysinfo info;sysinfo(&info);return info.uptime;}void initPrivate_Reg_Buf(int index,struct sPrivateReg Private_Reg_Buf[]){memset(&Private_Reg_Buf[index], 0, sizeof(struct sPrivateReg));Private_Reg_Buf[index].fd = -1;}void close_fd(int fd,struct sPrivateReg Private_Reg_Buf[]){int i;for(i = 0; i< MAXEPOLLSIZE; i++)if(Private_Reg_Buf[i].fd == fd){printf("close_fd(normal): %d", fd);Private_Reg_Buf[i].fd = -1;shutdown(fd, SHUT_RDWR);close(fd);return;}}int handle(int confd,int *index) {int rtcpnum;struct timeval tm,tm1;unsigned char buf[MAXLINE];rtcpnum=read(confd, buf, MAXLINE);if (rtcpnum == 0) {printf("client close the connection");close(confd);return -1;} if (rtcpnum < 0) {perror("read error");close(confd);return -1;}pthread_mutex_lock(&rs485busdata_mut);rs485busyflag=1;connfd=confd;Uart_send(fcom,(char *)buf,rtcpnum);gettimeofday(&tm, NULL);while(rs485busyflag){gettimeofday(&tm1, NULL);if(((tm1.tv_sec-tm.tv_sec)*1000+(tm1.tv_usec-tm.tv_usec)/1000)>=500){rs485busyflag=0;break;}else usleep(2000);}pthread_mutex_unlock(&rs485busdata_mut);return 0;}void DoTcpEvent1(int *index){int i,fd_index;int count=0;int  servPort =502+(*index);int listenq = 6;//监听队列int listenfd, connect_fd, kdpfd, nfds, n, curfds;struct sockaddr_in servaddr, cliaddr;socklen_t socklen = sizeof(struct sockaddr_in);struct epoll_event ev;struct epoll_event events[MAXEVENTS];struct sPrivateReg Private_Reg_Buf[MAXEPOLLSIZE];unsigned int datetime;for(i=0;i=0){initPrivate_Reg_Buf(fd_index,Private_Reg_Buf);Private_Reg_Buf[fd_index].fd = connect_fd;Private_Reg_Buf[fd_index].lastaccesstime = datetime;ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;ev.data.fd = connect_fd;if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, connect_fd, &ev) < 0){   fprintf(stderr, "epoll set insertion error: fd=%d",connect_fd);}}else{shutdown(connect_fd, SHUT_RDWR);close(connect_fd);printf("full tcp pool!");}}else if(events[n].events&EPOLLHUP)//#{epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev) ;close_fd(events[n].data.fd,Private_Reg_Buf);printf("EPOLLHUP fd: %d",events[n].data.fd);}else if(events[n].events&EPOLLERR){   /* read data from client */epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev) ;close_fd(events[n].data.fd,Private_Reg_Buf);printf("EPOLLERR fd: %d",events[n].data.fd);}else if(events[n].events&EPOLLIN){//recive_form_client(events[n].data.fd);struct sPrivateReg *pPrivate_Reg_Buf = findfd(events[n].data.fd,Private_Reg_Buf);if(pPrivate_Reg_Buf){pPrivate_Reg_Buf->lastaccesstime = gettickcount();if (handle(events[n].data.fd,index) < 0) {close_fd(pPrivate_Reg_Buf->fd,Private_Reg_Buf);}}}else{   /* read data from client */printf("UNKNOWN POLL MESSAGE fd: %d",events[n].data.fd);}}}close(listenfd);}int main(int argc, char **argv){pthread_t com,tcp;int baud;char dev[10],comdev[20];comdev[0]=0;//串口初始化if(argc!=3){fprintf(stderr,"Usage:comtcp baud devexample:comtcp 9600 ttySAC0");exit(1);}sscanf(argv[1],"%d",&baud);sscanf(argv[2],"%s",dev);strcat(comdev,"/dev/");strcat(comdev,dev);fcom= OpenDev(comdev);if(fcom){switch(baud){case 2400:set_speed(fcom,B2400);break;case 4800:set_speed(fcom,B4800);break;case 9600:set_speed(fcom,B9600);break;case 19200:set_speed(fcom,B19200);break;case 38400:set_speed(fcom,B38400);break;case 57600:set_speed(fcom,B57600);break;case 115200:set_speed(fcom,B115200);break;default:set_speed(fcom,B9600);printf("daufalt baud:B9600");break;}}else{printf("Can not open COM %s!",dev);exit(1);}if (set_Parity(fcom,8,1,'N')== FALSE){    printf("Set Parity Error");    exit(1);}comindex=0;tcpindex=0;pthread_create(&com,NULL,(void*)&DoComEvent,(void *)&comindex);pthread_create(&tcp,NULL,(void*)&DoTcpEvent1,(void *)&tcpindex);while (1){sleep(1);}close(connfd);//关闭设备close(fcom);return 0;}

使用说明

配置系统

编译源码将comtcp复制到系统某个路径下;

运行程序,执行命令

测试结果

准备下面两个调试软件:

打开软件,用网络调试软件以TCP客户端连接设备IP(例如192.168.1.15),502端口,串口调试软件连接到设备串口;

网络调试软件发送数据会在串口调试软件中收到,串口调试软件发送数据会在网络调试软件中收到;实现了串口与网口的数据互相转发;

下图为测试结果:

linux下c网络编程实现串口与网口的信息透传_串口网口数据透传程序相关推荐

  1. Linux下TCP网络编程-创建服务器与客户端

    一.前言 互联网概念诞生于20世纪60年代末,从9几年中国接入互联网开始到现在,生活的每个角落都能看到网络的使用.现在物联网时代.共享经济的到来,生活中不仅仅电脑.手机可以接入网络,身边的各个设备也能 ...

  2. Linux下Socket网络编程

    什么是Socket Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程, ...

  3. Linux下Socket网络编程send和recv使用注意事项

    1.send函数 ssize_t send( SOCKET s, const char *buf, size_t len, int flags ); (1)send先比较待发送数据的长度len和套接字 ...

  4. Linux下Socket网络编程之点对点聊天室

    1. 系统设计的目的与意义 掌握信号与信号处理的概念,了解点对点聊天室的设计需求,掌握相关的理论知识,切实掌握程序设计的分析方法,勇于实践,多参考开源项目和代码.实现点对点聊天室程序设计,Linux网 ...

  5. Linux下的C编程实战

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来, Linu ...

  6. Linux下的C编程实战(转载)

    http://www.cnblogs.com/alexusli/archive/2008/10/24/1318736.html Linux下的C编程实战(转载) (转自)http://www.cnbl ...

  7. Linux下的C编程实战(开发平台搭建,文件系统编程,进程控制与进程通信编程,“线程”控制与“线程”通信编程,驱动程序设计,专家问答)

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来,Linux ...

  8. linux应用之--网络编程

    linux网络编程 一:网络参考模型参考模型,如下图所示: 二:TCP/IP协议 TCP协议(传输控制协议)和UDP协议(用户数据包协议)是工作在传输层的.  其中TCP协议是面向连接的,UDP是面向 ...

  9. 网络编程与分层协议设计:基于linux平台实现,网络编程与分层协议设计:基于Linux平台实现...

    图书简介 本书以Linux网络套接字编程和网络分层协议的设计与程序实现为主题,详细介绍如何在Linux平台下进行套接字程序设计,并给出了一个基于分层协议的应用实例,用于模拟Linux网络协议栈中IP层 ...

最新文章

  1. 值得学习的寓言故事和哲理
  2. android4.0浏览器在eclipse中编译的步骤
  3. 从R-CNN到Mask R-CNN
  4. mysql查询交叉连接_复杂的MySQL查询,联合,交叉或自然连接?
  5. object取值_如何重写object虚方法
  6. 安卓 camera 调用流程_[Camera]Camera1 open、preview、take picture流程分析(3)
  7. 银屑病与寿命的关系(调研手稿七)
  8. 为特使建立控制平面的指南-部署权衡
  9. 【FLink】Flink checkpoint 实现数据连续计算 恢复机制 拓扑图 变化 如何处理
  10. GAdminHttpd:图形化的 Apache 打点对象
  11. 读谱对吉他手来说重要吗?试试它提升你的读谱效率
  12. g ++在linux下编译rapidxml 使用与过程中出现的问题解决
  13. php 16进制 声明,php16进制转换
  14. Hadoop加速器GridGain
  15. 大学c语言机试是老师阅卷么,最近,我们找了一些老师聊了聊
  16. 谷歌文档_如何比较Google文档中的文档
  17. 工厂方法模式练习:工厂方法模式在农场系统中的实现(IDEA)
  18. 明日之后怎么跳过实名认证_明日之后新手视频攻略如何跳过 明日之后新手教程内容说明...
  19. c语言奇数正偶数负,微原软件实验:统计正负数、奇偶数的个数
  20. 论文浏览(27) Long-Term Feature Banks for Detailed Video Understanding

热门文章

  1. 全志V3s硬件设计指南,全志V3s芯片资料
  2. JBOSS整套开发组件整合和配置方法
  3. SSHSSL弱加密算法漏洞修复
  4. CentOS7安装Proxychains实现linux代理
  5. 17、GATK使用简介 Part2/2
  6. 大学校园无线覆盖解决方案
  7. java实现mrp_java mrp算法实现
  8. 一团燃烧人性的实验之火——《野火(1959)》影评
  9. 老马群控使用教程之连接设备【手机支架、集控器、USB线】
  10. 计算机基础和wps office,办公装office还是wps好,wps和office哪个好用