socket编程之socket转串口_socket转232-程序员宅基地

技术标签: socket  

---------------------------------------------------------------------------------

系统环境:Centos 6.5

    开发板:s3c2440

---------------------------------------------------------------------------------

1、程序功能

该程序是一个运行在开发板上的client程序,连接到windows下usr-tcp调试工具模拟的server,接受串口和socket数据并转发

usr-tcp通过tcp服务器向client发送数据,client接受到数据后通过串口发回usr-tcp

usr-tcp通过串口向client发送数据,client接收到数据后通过socket发回usr-tcp

 




2、源代码

串口相关设置 serial.c

/*********************************************************************************
 *      Copyright:  (C) 2016 Lu Zengmeng<[email protected]>
 *                  All rights reserved.
 *
 *       Filename:  serial.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/01/2016)
 *         Author:  Lu Zengmeng <[email protected]>
 *      ChangeLog:  1, Release initial version on "08/01/2016 06:44:59 PM"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>

#define FAIL -1
#define OK   0
 
int speed_arr[] = {B115200,B57600,B38400,B19200,B9600,B4800,B2400,B1200,B600,B300,B110};
int name_arr[]  = { 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 600, 300, 110};

/* set baud rate */
void set_speed(int fd, int speed)
{
    int i;
    int status;
    struct termios options;

    tcgetattr(fd, &options);
    options.c_iflag &= ~ (INLCR | ICRNL | IGNCR);
    options.c_oflag &= ~(ONLCR | OCRNL);
    options.c_iflag &= ~(IXON);

    for( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
    {
        if(speed == name_arr[i])
        {
            tcflush(fd, TCIOFLUSH);/*empty input cache*/

            cfsetispeed(&options, speed_arr[i]);
            cfsetospeed(&options, speed_arr[i]);

            status = tcsetattr(fd, TCSANOW, &options);
            if(status != 0)
                   perror("tcsetattr fd");

            return;
        }
        tcflush(fd,TCIOFLUSH);/*empty input cache*/
    }
}


/**
 * *@brief 设置串口数据位,停止位和效验位
 * *@param fd 类型 int 打开的串口文件描述符
 * *@param databits 类型 int 数据位 取值 为 7 或者8
 * *@param stopbits 类型 int 停止位 取值为 1 或者2
 * *@param parity 类型 int 效验类型 取值为N,E,O,S
 * */
int set_parity(int fd,int databits,int stopbits,int parity)
{
    struct termios options;
    if ( tcgetattr( fd,&options) != 0)
    {
        perror("SetupSerial 1");
        return(FAIL);
    }
    options.c_cflag &= ~CSIZE;
    options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
    options.c_oflag  &= ~OPOST;   /*Output*/

    switch (databits) /*set datebits*/
    {
        case 7:
            options.c_cflag |= CS7;
            break;
        case 8:
            options.c_cflag |= CS8;
            break;
        default:
            fprintf(stderr,"Unsupported data size\n");
            return (FAIL);
    }

    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:
            fprintf(stderr,"Unsupported parity\n");
            return (FAIL);
    }
    /*set stopbits */
    switch (stopbits)
    {
        case 1:
            options.c_cflag &= ~CSTOPB;
            break;
        case 2:
            options.c_cflag |= CSTOPB;
            break;
        default:
            fprintf(stderr,"Unsupported stop bits\n");
            return (FAIL);
    }
    /* Set input parity options */
    if (parity != 'n')
        options.c_iflag |= INPCK;

    options.c_cc[VTIME] = 0; // 15 seconds
    options.c_cc[VMIN] = 0;

    tcflush(fd,TCIFLUSH); /* Update the optionsions and do it NOW */

    if (tcsetattr(fd,TCSANOW,&options) != 0)
    {
        perror("tcsetattr");
        return FAIL;
    }
    return (OK);
}
/**
 * *@breif open device
 * */
int open_dev(char *dev)
{
    int fd;

    fd = open( dev, O_RDWR|O_NOCTTY|O_NDELAY);
    if (fd < 0)
    {
        perror("open");
        return FAIL;
    }
    else
        return fd;
}

serial.h

/********************************************************************************
 *      Copyright:  (C) 2016 Lu Zengmeng<[email protected]>
 *                  All rights reserved.
 *
 *       Filename:  serial.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(08/01/2016)
 *         Author:  Lu Zengmeng <[email protected]>
 *      ChangeLog:  1, Release initial version on "08/01/2016 06:44:25 PM"
 *                 
 ********************************************************************************/
#include <stdio.h>

#ifndef __SERIAL_H__
#define __SERIAL_H__

extern int speed_arr[];
extern int name_arr[];
extern void set_speed(int fd, int speed);
extern int set_parity(int fd,int databits,int stopbits,int parity);
extern int open_dev(char *dev);

#endif
socket初始化连接 tcp.c

/*********************************************************************************
 *      Copyright:  (C) 2016 Lu Zengmeng<[email protected]>
 *                  All rights reserved.
 *
 *       Filename:  tcp.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/02/2016)
 *         Author:  Lu Zengmeng <[email protected]>
 *      ChangeLog:  1, Release initial version on "08/02/2016 08:09:55 AM"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "tcp.h"

/**************************************************************************************
 *  Description:
 *   Input Args:
 *  Output Args:
 * Return Value:
 *************************************************************************************/
int socket_init(void)
{

    int                    fd;
    struct sockaddr_in     serv_addr;


    bzero(&serv_addr,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port   = htons(PORT);

    if ((inet_pton(AF_INET,IPADDR,&serv_addr.sin_addr)) < 0)
    {
        perror("inet_pton");
        exit(1);
    }

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        perror("socket");
        exit(1);
    }

    if (-1 == connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)))
    {
        perror("connect");
        exit(1);
    }
    printf("connect sucesseful\n");

    return fd;
}
     /* ----- End of socket_init()  ----- */

tcp.h

/********************************************************************************
 *      Copyright:  (C) 2016 Lu Zengmeng<[email protected]>
 *                  All rights reserved.
 *
 *       Filename:  tcp.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(08/02/2016)
 *         Author:  Lu Zengmeng <[email protected]>
 *      ChangeLog:  1, Release initial version on "08/02/2016 08:22:06 AM"
 *                 
 ********************************************************************************/
#include <stdio.h>

#ifndef __TCP_H_
#define __TCP_H_

#define PORT             8003
#define IPADDR           "192.168.1.104"
extern int socket_init(void);

#endif

main.c

/*********************************************************************************
 *      Copyright:  (C) 2016 Lu Zengmeng<[email protected]>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/01/2016)
 *         Author:  Lu Zengmeng <[email protected]>
 *      ChangeLog:  1, Release initial version on "08/01/2016 06:45:37 PM"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>  
#include <string.h>  
#include <errno.h> 
#include <unistd.h>  

#include <sys/types.h>  
#include <sys/stat.h>  

#include <fcntl.h>   
#include <termios.h> 
#include <pthread.h> 

#include "serial.h" 
#include "tcp.h" 

#define  DEVICE      "/dev/ttyS1"
#define  BUF_SIZE    128

int    usrt_fd;
int    sock_fd;

void usrt_to_socket (void);
void socket_to_usrt (void);

/* start main */
int main(int argc,char **argv)
{
    int    ret;
    char   *dev = DEVICE;
    pthread_t sock,usrt;

    sock_fd = socket_init();
    usrt_fd = open_dev(dev);

    set_parity(usrt_fd,8,1,'N'); // 设置串口数据位、停止位、校验位
    set_speed(usrt_fd,9600); // 设置串口波特率

    ret = pthread_create(&sock,NULL,(void *)socket_to_usrt,NULL); // 创建sock线程接收socket数据
    if(ret < 0)
    {
        perror("phread_create");
        exit(1);
    }

    ret = pthread_create(&usrt,NULL,(void *)usrt_to_socket,NULL); // 创建usrt线程接收串口数据
    if(ret < 0)
    {
        perror("phread_create");
        exit(1);
    }

    pthread_join(sock,NULL); // 等待线程退出
    pthread_join(usrt,NULL);

    close(sock_fd);
    close(usrt_fd);

    printf("main exit...\n");
    return 0;
}


/**************************************************************************************
 *  Description:接收socket数据并通过串口转发
 *   Input Args:
 *  Output Args:
 * Return Value:
 *************************************************************************************/
void socket_to_usrt (void)
{
    printf("start socket_to_usrt...\n");
    int     n = 0;
    int     m = 0;
    char    buf[BUF_SIZE];

    while(1)
    {
        memset(buf,0,BUF_SIZE);
        n = read(sock_fd,buf,BUF_SIZE);
        if(n>0)
        {
            if(0==strncmp(buf,"exit",4)) // 收到exit时,线程退出
            {
                m = write(usrt_fd,buf,BUF_SIZE);
                if(m<0)
                {
                    perror("write to usrt");
                }
                break;
            }

            m = write(usrt_fd,buf,BUF_SIZE);
            if(m<0)
            {
                perror("write to usrt");
            }
        }
        else if(n<0)
        {
            perror("read from socket");
        }
    }

    printf("socket_to_usrt exit...\n");
    pthread_exit(0);
} /* ----- End of sock_to_usrt()  ----- */


/**************************************************************************************
 *  Description:接收串口数据并通过socket转发
 *   Input Args:
 *  Output Args:
 * Return Value:
 *************************************************************************************/
void usrt_to_socket (void)
{
    printf("start usrt_to_socket...\n");
    int     n = 0;
    int     m = 0;
    char    buf[BUF_SIZE];

    while(1)
    {
        memset(buf,0,BUF_SIZE);
        n = read(usrt_fd,buf,BUF_SIZE);
        if(n>0)
        {
            if(0==strncmp(buf,"exit",4)) // 收到exit时,线程退出
            {
                m = write(sock_fd,buf,BUF_SIZE);
                if(m<0)
                {
                    perror("write to sock");
                }
                break;
            }

            m = write(sock_fd,buf,BUF_SIZE);
            if(m<0)
            {
                perror("write to sock");
            }
        }

        else if(n<0)
        {
            perror("read from usrt");
        }
    }
    
    printf("usrt_to_socket exit...\n");
    pthread_exit(0);
} /* ----- End of usrt_to_sock()  ----- */
makefile

NAME=client
CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
EXTRA_CFLAGS+= -Wall -Werror
EXTRA_CFLAGS+= -lpthread
all:
        $(CC) $(EXTRA_CFLAGS) main.c serial.c tcp.c -o $(NAME)
        cp $(NAME) /tftp


3、调试助手下载

USR-TCP232-Test




版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_21111579/article/details/52134772

智能推荐

状态机图 java_文本处理(一)状态机(1)-程序员宅基地

文章浏览阅读176次。系统程序员成长计划-文本处理(一)状态机(1)o 有穷状态机的形式定义有穷状态机是一个五元组 (Q,Σ,δ,q0,F),其中:Q是一个有穷集合,称为状态集。Σ是一个有穷集合,称为字母表。δ: Q xΣQ称为状态转移函数。q0 是初始状态。F 是接受状态集。教科书上是这样定义有穷自动机的,这个形式定义精确的描述了有穷状态机的含义。但是大部分人(包括我自己)第一次看到它时,反复的读上几遍,仍然不知道..._自动门的控制器 有穷状态机

Beyond Compare4如何通过密钥连接SFTP进行文件夹的比较_beyondcompare连接sftp服务器-程序员宅基地

文章浏览阅读1.5k次。在网上搜索了很久没有找到相对应的资源特发布一篇关于此类的文章_beyondcompare连接sftp服务器

AndroidStudio项目提交到github以及工作中实际运用(详细步骤)_guihut readme 加载流程图-程序员宅基地

文章浏览阅读836次,点赞2次,收藏3次。在使用studio开发的项目过程中有时候我们想将项目发布到github上,以前都是用一种比较麻烦的方式(cmd)进行提交,最近发现studio其实是自带这种功能的,终于可以摆脱命令行了。 因为自己也没有做很深的研究,这里就先分享一下通过studio将自己的项目上传到github上的步骤。两个相关概念:git和githubGit是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项_guihut readme 加载流程图

oracle12c1使用远程图形进行安装_麒麟安装oracle12c数据库-程序员宅基地

文章浏览阅读1.9k次,点赞3次,收藏4次。应为最近安装了好几次了,而且每次使用静默安装12c1版都会失败,所以索性就记录一下图形化安装,方便后期的使用。_麒麟安装oracle12c数据库

office 2016出现错误,无法启动程序。。。是怎么回事?如何解决?_无法启动office 错误代码147-0-程序员宅基地

文章浏览阅读1.1w次,点赞4次,收藏2次。我刚刚在自己电脑上解决了相同的问题,将方法发上来供参考: 打开“服务”,在里面找到Microsoft Office ClickToRun Service服务,将它关闭,再启动,调成自动; 如果提示无法开启服务也可以这样操作亲测有效..._无法启动office 错误代码147-0

CSU 1558 和与积_多个数的和与积相等 bzoj-程序员宅基地

文章浏览阅读977次。CSU 1558 和与积 Time Limit: 1 Sec Memory Limit: 128 MB Special Judge Submit: 121 Solved: 69 Description构造N个正数(每个数不超过1000000),使所有数的和与所有数的积相差刚好等于D,按非递减序输出。Input多组测试数据(不超过1000组),每行两个正整数N和D。(2<=N<=1000,_多个数的和与积相等 bzoj

随便推点

初始化vector实例的7种方法_创建和初始化vector的方法,每种都给出一个实例?当然也可以把deque与list写出来-程序员宅基地

文章浏览阅读1.4k次。转载 https://blog.csdn.net/qiaoruozhuo/article/details/52086286/* Name: Copyright: Author: Date: 01-08-16 16:01 Description: 初始化vector实例的7种方法 */ #include&lt;iostream&gt; #..._创建和初始化vector的方法,每种都给出一个实例?当然也可以把deque与list写出来

免费开通PTrade与QMT量化交易系统_ptrade交易系统官网-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏12次。免费的券商量化系统开通,急速、安全_ptrade交易系统官网

c语言中set 函数,C里边的STL里边的Set函数-程序员宅基地

文章浏览阅读2.2k次。set函数的用法:这是一个集合函数,这个函数可以处理很多的元素,这些元素可以去重,把相同的元素都去掉,剩下不一样的元素,而且还可以自动给这些元素来排序,从小到大的顺序来排序。这里我们先来举个例子:比如:#include #include using namespace std; int main() { set a; a.insert(1); a.insert(9); a.insert(6); a..._c语言set

牛笔了!字节跳动大佬整理:CSS 核心知识(万字长文,值得收藏!)_字节跳动公司 reset css-程序员宅基地

文章浏览阅读1.1k次,点赞4次,收藏14次。本篇文章围绕了 CSS 的核心知识点和项目中常见的需求来展开。虽然行文偏长,但较基础,适合初级中级前端阅读,阅读的时候请适当跳过已经掌握的部分。这篇文章断断续续写了比较久,也参考了许多优秀的文章,但或许文章里还是存在不好或不对的地方,请多多指教,可以评论里直接提出来哈。小tip:后续内容更精彩哦。核心概念和知识点语法CSS 的核心功能是将 CSS 属性设定为特定的值。一个属性与值的键值对被称为声明(declaration)。color: red;复制代码而如果将一个或者多个声明用 {} _字节跳动公司 reset css

Shell读取mysql数据_while read -a row+读取sql查询结果+shell-程序员宅基地

文章浏览阅读762次。今天有个需求需要写个shell读取mysql记录,操作一些文件,搜索了一下踩了些坑记录一下shell2.0写法注释:注意"done< <(“的写法,第一个”<“要和"done"之间没空格,两个”<“之间有一个空格,”<" 和"("之间没空格COMMAND1="mysql -h${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME}e.g.while read -a rowdo echo "._while read -a row+读取sql查询结果+shell

汉明码_cdsn 汉明-程序员宅基地

文章浏览阅读4k次,点赞7次,收藏37次。汉明码实现原理汉明码(Hamming Code)是广泛用于内存和磁盘纠错的编码。汉明码不仅可以用来检测转移数据时发生的错误,还可以用来修正错误。(要注意的是,汉明码只能发现和修正一位错误,对于两位或者两位以上的错误无法正确和发现)。汉明码的实现原则是在原来的数据的插入k位数据作为校验位,把原来的N为数据变为m(m = n +k)位编码。其中编码时要满足以下原则:2^k - 1 &gt..._cdsn 汉明