socket编程之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<1540999272@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  serial.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/01/2016)
 *         Author:  Lu Zengmeng <1540999272@qq.com>
 *      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<1540999272@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  serial.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(08/01/2016)
 *         Author:  Lu Zengmeng <1540999272@qq.com>
 *      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<1540999272@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  tcp.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/02/2016)
 *         Author:  Lu Zengmeng <1540999272@qq.com>
 *      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<1540999272@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  tcp.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(08/02/2016)
 *         Author:  Lu Zengmeng <1540999272@qq.com>
 *      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<1540999272@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/01/2016)
 *         Author:  Lu Zengmeng <1540999272@qq.com>
 *      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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值