介绍
tcp作为服务端,监听端口8888,实现串口透传,这里是使用select监听tcp的receive和串口的read,单工通信
程序
#include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <linux/serial.h> #include <sys/ioctl.h> #include <sys/select.h> #include <termios.h> void Test_err(int flg) { if(flg<0) { perror(strerror(errno)); exit(1); } } int main(int argc, char** argv) { printf("usage : %s <port,default is 8888>\n",argv[0]); printf("tcp-server...enter\n"); unsigned char* uart_port="/dev/ttyS2"; unsigned int baudRate= B9600; // uart-------------------------------------------------------- int uart_fd=open(uart_port, O_RDWR | O_NOCTTY | O_NDELAY); struct termios newtio; memset(&newtio,0, sizeof( newtio )); newtio.c_cflag=0; newtio.c_iflag=0; newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; newtio.c_cflag |= CS8; newtio.c_cflag &= ~PARENB; newtio.c_cflag &= ~CSTOPB; newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 0; cfsetispeed(&newtio, baudRate); cfsetispeed(&newtio, baudRate); tcflush(uart_fd,TCIFLUSH); if((tcsetattr(uart_fd,TCSANOW,&newtio))!=0) { perror("uart open error\n"); return -1; } int portfd; #if (__GNUC__ == 4 && __GNUC_MINOR__ == 3) struct my_serial_rs485 rs485conf; struct my_serial_rs485 rs485conf_bak; #else struct serial_rs485 rs485conf; struct serial_rs485 rs485conf_bak; #endif portfd=uart_fd; /* Driver-specific ioctls: ...\linux-3.10.x\include\uapi\asm-generic\ioctls.h */ #define TIOCGRS485 0x542E #define TIOCSRS485 0x542F if (ioctl (portfd, TIOCGRS485, &rs485conf) < 0) { /* Error handling.*/ // Log::Inf("ioctl TIOCGRS485 error.\n"); printf( "[ERR] ioctl TIOCGRS485 error.\n"); } /* Enable RS485 mode: */ rs485conf.flags |= SER_RS485_ENABLED; /* Set logical level for RTS pin equal to 1 when sending: */ rs485conf.flags |= SER_RS485_RTS_ON_SEND; //rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; /* set logical level for RTS pin equal to 0 after sending: */ rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); //rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND); /* Set rts delay after send, if needed: */ rs485conf.delay_rts_after_send = 0x80; if (ioctl (portfd, TIOCSRS485, &rs485conf) < 0) { /* Error handling.*/ printf("ioctl TIOCSRS485 error.\n"); } if (ioctl (portfd, TIOCGRS485, &rs485conf_bak) < 0) { /* Error handling.*/ printf("ioctl TIOCGRS485 error.\n"); } /*----------------------------------------------------*/ unsigned char test_msg[]="this is send by uart\n"; int uart_sent_cnt = write(uart_fd, test_msg, sizeof(test_msg)); // tcp-------------------------------------------------------- short listenPort=8888; int listen_fd=-1; int accept_fd=-1; int flags; int max_listen_num=10; unsigned char r_buf[255]; int n; struct sockaddr_in server_addr; struct sockaddr_in clinet_addr; if (argc ==2) { listenPort=atoi(argv[1]); } printf("set port is %d\n",listenPort); listen_fd=socket(AF_INET, SOCK_STREAM, 0); Test_err(listen_fd); memset(&server_addr,0,sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(listenPort); int i = 1;/* 允许重复使用本地地址与套接字进行绑定 */ setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); flags=bind(listen_fd, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)); Test_err(flags); flags= listen(listen_fd, max_listen_num); Test_err(flags); int clinet_addr_len=sizeof(clinet_addr); __ACCEPT_AGAIN__: accept_fd= accept(listen_fd, (struct sockaddr *)&clinet_addr, &clinet_addr_len); // show clinet message printf("accept_fd is %d \n",accept_fd); printf("port=%d\n",ntohs(clinet_addr.sin_port)); unsigned char strbuf[20]; inet_ntop(AF_INET,&clinet_addr.sin_addr,strbuf,sizeof(strbuf)); printf("ip=%s\n",strbuf); memset(r_buf , 0, sizeof(r_buf)); int maxfd; fd_set rset, allset; struct timeval tv; FD_ZERO(&allset); FD_SET(uart_fd, &allset); FD_SET(accept_fd, &allset); memset(&tv, 0, sizeof(tv)); tv.tv_usec = 1000 * 1000; int len=0; while (accept_fd) { rset=allset; maxfd=(accept_fd>uart_fd?accept_fd:uart_fd); flags=select(maxfd + 1, &rset, NULL, NULL, &tv); Test_err(flags); // get from tcp>>>>>uart if (FD_ISSET(accept_fd, &rset)) { n = recv(accept_fd, r_buf, 100, 0); Test_err(n); if(n) { //write(0,r_buf,n); printf("Get from tcp %d\n",n); write(uart_fd,r_buf,n); } else { printf("socket is disconnect\n"); goto __ACCEPT_AGAIN__; } } // get from uart>>>>tcp else if (FD_ISSET(uart_fd, &rset)) { usleep(100000);//100ms 这里等待接受多一点的数据 int ret = read(uart_fd, (char*)r_buf,sizeof(r_buf)); if (ret < 0) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR)) { printf("Serial,read timeout error:%s. ignore ti!!!", strerror(errno)); ret = 0; } } else { printf("Get from uart %d\n",ret); send(accept_fd, r_buf, ret, 0); } } } printf("tcp-server...exit\n"); return 0; }