串口通信+TCP网络通信简单综合实例

串口通信+TCP网络通信简单综合实例

串口通信加上TCP网络通信之后就可以简单实现本地设备的联网功能了,哈哈,话不多说,直接上代码。

总体上还是C/S模式,但是这个客户端加上了对串口的操作而已,思路很简单,只不过应用过程中可能会碰到一些棘手的问题,比如和终端的交互协议采用什么,协议的复杂程度如何,通信时的同步问题,稳定性问题等等。这里我们都先不去考虑,下面的代码仅仅只是设备利用串口实现了和远程服务器的通信,还未做任何优化。

1.服务器部分:服务器基本不变,只需要和客户端进行通信即可,和串口无任何交互。所以其代码不变,和TCP网络通信的服务端代码相同。

 

/*
 * 文件:tcp_server.c
 * 内容:利用TCP实现客户端和服务器的实时聊天。
 * 注  :服务器的端口号及IP,客户端的端口号及IP的输入通过main函数的argc和argv来实现。
 * 未输入端口号的话使用默认端口号,服务器为1111,客户端为2222。
 * 编译:gcc tcp_server.c -o ser -lpthread
 * 运行:./ser 127.0.0.1 7788 5
 */
 
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<time.h>
#include<errno.h>
#include<pthread.h>
#include<arpa/inet.h>
 
#define SPORT 1111
#define CPORT 2222
#define IP "127.0.0.1"
#define MAXLEN 1024
 
struct network_info
{
    struct sockaddr addr;
    int addr_len;
    int sock;
}target = {0,0,0};
 
void* myrecv(void* arg)
{
    int new_fd = 0,len = 0;
    char buf[MAXLEN] = {'\0'};
    time_t t;
    struct network_info netinfo;
    netinfo = *((struct network_info*)arg);
    new_fd = netinfo.sock;
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf)-1);
        len = recv(new_fd,buf,sizeof(buf) - 1,0);
        if(len > 0)
        {
            t = time(NULL);
            printf("&client:%s    @%s\n",buf,ctime(&t));
        }
        else if(len < 0)
        {
            printf("recv msg error,error code = %d,error msg = %s\n",errno,strerror(errno));
            break;
        }
        else
        {
            printf("client is quit\n");
            close(new_fd);
            break;
        }
    }
}
 
void* mysend(void* arg)
{
    int new_fd = 0,len = 0;
    char buf[MAXLEN] = {'\0'};
    struct network_info netinfo;
    netinfo = *((struct network_info*)arg);
 
    new_fd = netinfo.sock;
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf));
 
        gets(buf);
        if(!strncasecmp(buf,"quit",4))
        {
            printf("I will close the connect\n");
            sleep(1);
            close(new_fd);
            exit(EXIT_FAILURE);
        }
 
        len = sendto(new_fd,buf,strlen(buf),0,(struct sockaddr*)(&(netinfo.addr)),netinfo.addr_len);
        if(len < 0)
        {
            printf("msg is:%s,send failer,errno is %d,errno message is:%s\n",buf,errno,strerror(errno));
            break;
        }
    }
}
 
int main(int argc,char* argv[])
{
    int pid = 0,sock_fd = 0,new_fd = 0;
    socklen_t len;
    struct sockaddr_in self_addr,their_addr;
    unsigned int myport,lisnum;
    char buf[MAXLEN] = {'\0'};
    char ip[17] = {'\0'};
    time_t t;
    pthread_t pthread1,pthread2;
 
    if(argv[2] && argc >=3)
        myport = atoi(argv[2]);
    else
        myport = SPORT;
 
    if(argv[3] && argc >= 4)
        lisnum = atoi(argv[3]);
    else
        lisnum = 3;
 
    //创建套接字
    sock_fd = socket(AF_INET,SOCK_STREAM,0);
    if(sock_fd < 0)
    {
        perror("socket error");
        exit(EXIT_FAILURE);
    }
 
    //绑定自己的端口号
    memset(&self_addr,0,sizeof(self_addr));
    self_addr.sin_family = AF_INET;
    self_addr.sin_port = htons(myport);
    if(argv[1])
        self_addr.sin_addr.s_addr = inet_addr(argv[1]);
    else
        self_addr.sin_addr.s_addr = INADDR_ANY;
 
    if(bind(sock_fd,(struct sockaddr*)&self_addr,sizeof(self_addr)) == -1)
    {
        perror("bind error");
        exit(EXIT_FAILURE);
    }
 
    //监听
    if(listen(sock_fd,lisnum) == -1)
    {
        perror("listen error");
        exit(EXIT_FAILURE);
    }
 
    //接受客户端的连接请求
    memset(&their_addr,0,sizeof(their_addr));
    len = sizeof(their_addr);
    printf("wait for connect\n");
    while(1)
    {
        if((new_fd = accept(sock_fd,(struct sockaddr*)&their_addr,&len)) == -1)
        {
            printf("len=%d,new_fd=%d\n",len,new_fd);
            perror("accept error");
            exit(EXIT_FAILURE);
        }
        printf("=====================================================================\n");
        printf("client connect ok\n");
        printf("though i am a server,but if you want to shutdown,please print 'quit'.\n");
        printf("=====================================================================\n");
        memcpy(&(target.addr),&(their_addr),len);
        target.addr_len = len;
        target.sock = new_fd;
 
        //创建线程用于进程间通信
        pthread_create(&pthread1,NULL,myrecv,(void*)&target);
        pthread_create(&pthread2,NULL,mysend,(void*)&target);
    }
 
    pthread_join(pthread1,NULL);
    pthread_join(pthread2,NULL);
    close(new_fd);
    close(sock_fd); //关闭套接字
 
    return 0;
}

 

 

 

 

 

2.客户端部分(加入了串口操作,而且在多线程操作时仅仅做了简单处理,对了,关于串口操作部分,大家可以去看我转载的串口编程博文)

 

/*
 * 文件:tcp_client.c
 * 内容:利用TCP实现客户端和服务器的实时聊天,以及串口操作。
 * 注  :服务器的端口号及IP,客户端的端口号及IP的输入通过main函数的argc和argv来实现。
 * 未输入端口号的话使用默认端口号,服务器为1111,客户端为2222。
 * 编译:gcc tcp_client.c -o cli -lpthread
 * 运行:./cli 127.0.0.1 7788(注:这个是服务器端的地址和端口号)
 */
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include <arpa/inet.h>
#include<errno.h>
#include<time.h>
#include<pthread.h>
#include"uart0_open.h"
#include"uart0_init.h"
#include"uart0_send.h"
#include"uart0_recv.h"
#include"uart0_close.h"
 
#define IP "127.0.0.1"
#define SPORT 1111
#define CPORT 2222
#define MAXLEN 1024
 
int fd[2] = {0};
 
void* myrecv() //接收服务器信息后进行处理
{
    int len = 0;
    char buf[MAXLEN] = {'\0'};
    time_t t;
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf)-1);
        len = recv(fd[0],buf,sizeof(buf) - 1,0);
        if(len > 0)
        {
            t = time(NULL);
            printf("**********************************\n");
            printf("&server:%s\n",buf);
            printf("**********************************\n");
            UART0_Send(fd[1],buf,strlen(buf)); //收到服务器消息后发给串口
            printf("@%s\n",ctime(&t));
        }
        else if(len < 0)
        {
            printf("recv msg errno,errno code = %d,errno msg = %s\n",errno,strerror(errno));
            break;
        }
        else
        {
            printf("connect server error,it will be quit in 3 seconds later...\n");
            sleep(3);
            exit(EXIT_FAILURE);
        }
    }
}
 
void* mysend() //发送信息给服务器
{
    int len = 0;
    char buf[MAXLEN] = {'\0'};
 
    while(1)
    {
        memset(buf,'\0',sizeof(buf));
 
        UART0_Recv(fd[1],buf,sizeof(buf)-1); //从串口处获取要发送给服务器的信息
        if(!strncasecmp(buf,"quit",4))
        {
            printf("I will close the connect ...\n");
            sleep(1);
            exit(EXIT_FAILURE);
        }
        len = send(fd[0],buf,strlen(buf),0);
        if(len < 0)
        {
            printf("msg is:%s,send failer,errno is %d,errno message is:%s\n",buf,errno,strerror(errno));
            break;
        }
    }
}
 
 
int main(int argc,char* argv[])
{
    int err = 0;
    socklen_t len;
    struct sockaddr_in their_addr;
    unsigned int their_port;
    char buf[MAXLEN] = {0};
    pthread_t pthread1,pthread2;
 
    //创建socket
    if((fd[0] = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        perror("socket error");
        exit(EXIT_FAILURE);
    }
 
    //发送连接服务器的请求
    memset(&their_addr,0,sizeof(their_addr));
    their_addr.sin_family = AF_INET;
    if(argv[2] && argc >= 3)
        their_port = atoi(argv[2]);
    else
        their_port = SPORT;
    their_addr.sin_port = htons(their_port);
 
    if(argv[1] && argc >=2)
    {
        if(inet_aton(argv[1],(struct in_addr *)&their_addr.sin_addr.s_addr) == 0)
        {
            perror("argv[1]");
            exit(EXIT_FAILURE);
        }
    }
    else
        their_addr.sin_addr.s_addr = inet_addr(IP);
 
    if(connect(fd[0],(struct sockaddr*)(&their_addr),sizeof(their_addr)) == -1)
    {
        perror("connect error");
        exit(EXIT_FAILURE);
    }
 
    //打开串口,返回文件描述符
    fd[1] = UART0_Open(fd[1],"/dev/ttyS1");
    do {
        err = UART0_Init(fd[1],115200,0,8,1,'N');
        printf("set port exactly!\n");
    } while (-1 == err || -1 == fd[1]);
 
    printf("==============================================\n");
    printf("connect success!\n");
    printf("if you want to leave,please print 'quit'.\n");
    printf("==============================================\n");
 
    pthread_create(&pthread1,NULL,myrecv,NULL); //创建线程
    pthread_create(&pthread2,NULL,mysend,NULL);
 
    pthread_join(pthread1,NULL); //等待线程结束
    pthread_join(pthread2,NULL);
    UART0_Close(fd[1]); //关闭串口
    close(fd[0]); //关闭套接字
 
    return 1;
}

 

 

 

 

 

结果:记得选择合适版本的交叉编译器。

 

  • 3
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值