树莓派tcp服务器性能,【树莓派3B+测评】TCP客户端&阻塞线程创建&取消

【树莓派3B+测评】TCP客户端&阻塞线程创建&取消

[复制链接]

本帖最后由 donatello1996 于 2018-12-19 09:30 编辑

【树莓派3B+测评】TCP客户端&阻塞线程创建&取消

在Linux系统中,TCP通信还有一个常用角色是客户端,像树莓派这种板子,经常充当从机角色连接电脑主机,在这种情况下,以客户端身份连接主机是比较易于理解且占用资源较少的做法,主机的服务器一直开着,树莓派从机可按需分时进行TCP连接或者一直检测主机服务器是否掉线以确保通信的稳定,那么,在上一帖中提到过,TCP通信要同时收发且互不干扰,必须开启多一个用于发送的线程,当TCP连接断开的时候,这个线程要挂起或者取消,在频繁的客户端连接主机的过程中,自然也就会频繁地开启或关闭TCP发送线程,这就涉及到线程里面最简单的创建和取消操作。

首先让树莓派以客户端身份连接电脑主机TCP服务器,非常简单,只需要用到socket()和connect()两个函数:

socklen_t addrsize=sizeof(struct sockaddr);

struct sockaddr_in girladdr;

bzero(&girladdr,sizeof(girladdr)); // 清零

girladdr.sin_family=AF_INET;

girladdr.sin_port=htons(10086); //host-->network

girladdr.sin_addr.s_addr=inet_addr("169.254.122.1");

connect(fd_socket,(struct sockaddr *)&girladdr,addrsize);

如果是做一个循环检测主机TCP服务器是否存在的算法,就使用三个while循环即可:

while(1)

{

while(1)

{

fd_socket=socket(AF_INET,SOCK_STREAM,0);

if(fd_socket==-1)

{

printf("套接字初始化失败!\n");

return -1;

}

ret=connect(fd_socket,(struct sockaddr *)&girladdr,addrsize);

if(ret==0)

{

printf("与服务器建立连接\n");

break;

}

}

while(1)

{

bzero(recvbuf,100);

ret=recv(fd_socket,recvbuf,100,0);

if(ret==0)

{

printf("与服务器失去连接\n");

break;

}

printf("服务器端发来信息:%s\n",recvbuf);

}

}

另外,还要开辟一个用于TCP输入字符串发送的线程,与上一帖一样:

int fd_socket;

pthread_t id1;

unsigned char sendbuf[100],recvbuf[100];

void *Thread_Send_buf(void *arg)

{

int len;

while(1)

{

bzero(sendbuf,100);

scanf("%s",sendbuf);

//printf("----\n");

for(len=0;sendbuf[len]!='\0';len++);

//printf("%d\n",Raspi_DHT11_Read());

send(fd_socket,sendbuf,len,0);

}

}

要将线程的建立&取消和TCP客户端循环连接服务器的代码结合起来用,才可以实现本帖的功能:

int fd_socket;

pthread_t id1;

unsigned char sendbuf[100],recvbuf[100];

void *Thread_Send_buf(void *arg)

{

int len;

while(1)

{

bzero(sendbuf,100);

scanf("%s",sendbuf);

for(len=0;sendbuf[len]!='\0';len++);

send(fd_socket,sendbuf,len,0);

}

}

int main()

{

int i=0;

int ret=-1;

socklen_t addrsize=sizeof(struct sockaddr);

struct sockaddr_in girladdr;

bzero(&girladdr,sizeof(girladdr)); // 清零

girladdr.sin_family=AF_INET;

girladdr.sin_port=htons(10086); //host-->network

girladdr.sin_addr.s_addr=inet_addr("169.254.122.1");

int thread_1=0;

while(1)

{

while(1)

{

fd_socket=socket(AF_INET,SOCK_STREAM,0);

if(fd_socket==-1)

{

printf("套接字初始化失败!\n");

return -1;

}

ret=connect(fd_socket,(struct sockaddr *)&girladdr,addrsize);

if(ret==0)

{

printf("与服务器建立连接\n");

ret=pthread_create(&id1,NULL,Thread_Send_buf,NULL);

if(ret==0)

printf("TCP发送阻塞线程被创建\n");

break;

}

}

while(1)

{

bzero(recvbuf,100);

ret=recv(fd_socket,recvbuf,100,0);

if(ret==0)

{

printf("与服务器失去连接\n");

ret=pthread_cancel(id1);

if(ret==0)

printf("TCP发送阻塞线程被取消\n");

break;

}

printf("服务器端发来信息:%s\n",recvbuf);

}

}

}

看看效果,运行程序之后,树莓派会一直检测主机的TCP服务器是否开启,如果开启了就连接,并可正常使用TCP收发:

a26d678767e8b431ecd7a25f1936bdc5.gif

34.jpg (236.29 KB, 下载次数: 0)

2018-12-19 09:29 上传

a26d678767e8b431ecd7a25f1936bdc5.gif

35.jpg (237.58 KB, 下载次数: 0)

2018-12-19 09:29 上传

a26d678767e8b431ecd7a25f1936bdc5.gif

36.jpg (213.5 KB, 下载次数: 0)

2018-12-19 09:29 上传如果主机主动断开连接,那么树莓派端一样会检测到:

a26d678767e8b431ecd7a25f1936bdc5.gif

37.jpg (217.5 KB, 下载次数: 0)

2018-12-19 09:29 上传如果主机再次开启TCP服务器,那么树莓派会在十几秒之后重新握手建立连接:

a26d678767e8b431ecd7a25f1936bdc5.gif

38.jpg (218.75 KB, 下载次数: 0)

2018-12-19 09:29 上传

至于为什么是十几秒呢,这个据以前的Linux大佬说,TCP端口重新开启需要十几秒的时间。

即使连接是断开之后再建立的,仍可正常收发:

a26d678767e8b431ecd7a25f1936bdc5.gif

39.jpg (222.7 KB, 下载次数: 0)

2018-12-19 09:29 上传

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值