网络串口转发

//服务器端代码 server.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

int set_opt(int,int,int,char,int);
 
int main(int argc, char **argv)
{
    struct sockaddr_in servaddr;
    char recvline[1024];
                                    //SOCK_STREAM
    int sockfd = socket(PF_INET, SOCK_DGRAM, 0);
 
    //服务器 ip port
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(50001);
 
    //fcntl(sockfd, F_SETFL,O_NONBLOCK);//设置为非阻塞,根据具体需要决定是否需要非阻塞模式
    bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    
    
    int fd,nByte;
    char *uart3 = "/dev/ttyUSB0";
    
    int ret;

    if((fd=open(uart3,O_RDWR,0777))<0)
    {
        printf("failed\n");
    }
    else{
        printf("success\n");
        set_opt(fd, 115200, 8, 'N', 1); 

    }

    while(1)
    {
        struct sockaddr_in addrClient;
        int sizeClientAddr = sizeof(struct sockaddr_in);
        
        memset(recvline, 0, sizeof(recvline));
        
        ret = recvfrom(sockfd, recvline, 1024, 0, (struct sockaddr*)&addrClient,(socklen_t*)&sizeClientAddr);
        
        if(ret != 0)
        {
            char *pClientIP =inet_ntoa(addrClient.sin_addr);
 
            printf("%s-%d(%d) says:%s\n",pClientIP,ntohs(addrClient.sin_port),addrClient.sin_port, recvline);
            
            write(fd, recvline, ret);
        }
        
    }
    
    close(fd);
    close(sockfd);
}


//串口通用初始化函数
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
    struct termios newtio,oldtio;//定义结构体newtio和oldtio
    //将原串口的数据取到oldtio
    if  ( tcgetattr( fd,&oldtio)  !=  0) { 
        perror("SetupSerial 1");
        return -1;
    }
    //将newio清零和设置c_cflag
    bzero( &newtio, sizeof( newtio ) );
    newtio.c_cflag  |=  CLOCAL | CREAD;//使能接收和忽略控制线
    newtio.c_cflag &= ~CSIZE;
    //设置数据位
    switch( nBits )
    {
        case 7:
            newtio.c_cflag |= CS7;
            break;
        case 8:
            newtio.c_cflag |= CS8;
            break;
    }
    //设置校验位
    switch( nEvent )
    {
        //偶校验
        case 'O':
            newtio.c_cflag |= PARENB;//使能奇偶校验
            newtio.c_cflag |= PARODD;//偶校验
            newtio.c_iflag |= (INPCK | ISTRIP);//输入校验并忽略第八位
            break;
        case 'E': 
            newtio.c_iflag |= (INPCK | ISTRIP);
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;//取消偶校验(置零偶校验位),开启奇校验
            break;
        case 'N':  
            newtio.c_cflag &= ~PARENB;//不进行奇偶校验
            break;
    }
    //设置波特率
    switch( nSpeed )
    {
        case 2400:
            cfsetispeed(&newtio, B2400);
            cfsetospeed(&newtio, B2400);
            break;
        case 4800:
            cfsetispeed(&newtio, B4800);
            cfsetospeed(&newtio, B4800);
            break;
        case 9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        case 115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            break;
        case 460800:
            cfsetispeed(&newtio, B460800);
            cfsetospeed(&newtio, B460800);
            break;
        default:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
    }
    //设置停止位
    if( nStop == 1 )
        newtio.c_cflag &=  ~CSTOPB;//一位停止位
    else if ( nStop == 2 )
        newtio.c_cflag |=  CSTOPB;//两位停止位

    newtio.c_cc[VTIME]  = 0;//不设置读取超时
    newtio.c_cc[VMIN] = 0;//读取最小字符数为0

    tcflush(fd,TCIFLUSH);//清空缓冲区
    
    //使配置生效
    if((tcsetattr(fd,TCSANOW,&newtio))!=0)
    {
        perror("com set error");
        return -1;
    }
    //    printf("set done!\n\r");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值