我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么使用C++ Thread实现简单的socket多线程通信

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么使用C++ Thread实现简单的socket多线程通信

本篇内容介绍了“怎么使用C++ Thread实现简单的socket多线程通信”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

服务端

多线程功能放在腾讯云服务器上,代码如下:

#include "tcpserver.h"#include <thread>#include <mutex>TcpServer server;mutex tcp_mutex;void tcpFunc(int clientfd);int main(int argc, char *argv[]){    if (server.initServer(6666) == false)    {        cout << "服务端初始化失败!!!" << endl;        return -1;    }    vector<thread> tcp_vec;    while (true)    {        if (!server.tcpAccept())        {            continue;        }        tcp_vec.emplace_back(tcpFunc, server.m_connectfd);        // thread tcpThread(tcpFunc, server.m_connectfd);        // if (tcpThread.joinable())        if(tcp_vec.back().joinable())        {            // cout << "Tcp thread " << tcpThread.get_id() << "is joinable!" << endl;            cout << "Tcp thread " << tcp_vec.back().get_id() << " is joinable!" << endl;            tcp_vec.back().detach();        }    }    return 0;}void tcpFunc(int clientfd){    int buf_len = 0;    char buffer[1024];    while (true)    {        unique_lock<mutex> tcplck(tcp_mutex);        memset(buffer, 0, sizeof(buffer));        if (!server.tcpRecv(clientfd, buffer, &buf_len, 5))        {            cout << "接收客户端数据失败!" << endl;            tcplck.unlock();            break;        }        cout << "服务端接收数据:" << buffer << endl;        strcpy(buffer, "I am your father!");        if (!server.tcpSend(clientfd, buffer, sizeof(buffer)))        {            cout << "向客户端发送数据失败!" << endl;            tcplck.unlock();            break;        }        tcplck.unlock();                usleep(100);    }    cout << "通信异常!" << endl;    return;}

实在是很简单,贻笑大方了

有几个注意点:

  • 全局变量在main函数执行完后会销毁,线程中用到了全局变量server,线程detach后要保证数据的收发,就要保持server的生存期,这里体现为在main中循环等待客户端的连接

  • 要用锁锁住线程中server的操作,避免不同线程同时操作server造成混乱

  • usleep(100);是为了避免不同线程争抢同一把锁而造成死锁的发生

ROS客户端

#include "tcpclient.h"#include <ros/ros.h>#include <geometry_msgs/Twist.h>TcpClient client;string send_str = "I am king of the world!";char recv_buff[1024];void client_callback(const geometry_msgs::Twist::ConstPtr &msg){    cout << "vel X:" << msg->linear.x << ";vel Y:" << msg->linear.y << ";angular Z:" << msg->angular.z << endl;    if (!client.tcpSend(client.m_sockfd, send_str.data(), send_str.size()))    {        cout << "向服务端发送报文失败!" << endl;    }    if (!client.tcpRecv(client.m_sockfd, recv_buff, NULL, 10))    {        cout << "从服务端接收报文失败!" << endl;    }    cout << "接收服务端报文:" << recv_buff << endl << endl;}int main(int argc, char **argv){    ros::init(argc, argv, "joystick_client");    ros::NodeHandle nh;    string server_ip = "1.116.137.21";    string loop_ip = "127.0.0.1";    if (client.connectToServer(server_ip.data(), 6666) == false)    {        cout << "连接失败!!!" << endl;        return -1;    }    ros::Subscriber sub = nh.subscribe("/cmd_vel", 1, client_callback);    ros::spin();}

很简单,订阅了手柄发布的话题/cmd_vel,在回调函数中和服务端通讯

话题的发布频率是10Hz,意味着和服务端通讯的频率也是10Hz

普通客户端

#include "tcp/tcpclient.h"int main(int argc, char **argv){    TcpClient client;    string server_ip = "1.116.137.21";    string loop_ip = "127.0.0.1";    if (client.connectToServer(server_ip.data(), 6666) == false)    {        cout << "连接失败!!!" << endl;        return -1;    }    cout << "成功连接服务器!" << endl;    char buff[1024];    while (true)    {        memset(buff, 0, sizeof(buff));        sprintf(buff, "Ouch!");        if (!client.tcpSend(client.m_sockfd, buff, sizeof(buff)))        {            cout << "向服务端发送报文失败!" << endl;            return -1;        }        memset(buff, 0, sizeof(buff));        if (!client.tcpRecv(client.m_sockfd, buff, NULL, 5))        {            cout << "从服务端接收报文失败!" << endl;            return -1;        }        cout << "接收服务端报文:" << buff << endl << endl;        sleep(0.1);    }    return 0;}

这里sleep(0.1);是为了模拟ROS中话题的频率

sleep过长会导致服务端阻塞等待该客户端的消息,从而导致其余客户端与服务端的通信失败(如果客户端中允许的通信延时很短的话)

运行效果

云服务器上的服务端

[root@VM-4-11-centos bin]# ./server_thread 
Tcp thread 140662362572544 is joinable!
服务端接收数据:I am king of the world!
服务端接收数据:I am king of the world!
服务端接收数据:I am king of the world!
服务端接收数据:I am king of the world!
Tcp thread 140662354179840 is joinable!
服务端接收数据:I am king of the world!
服务端接收数据:Ouch!
服务端接收数据:I am king of the world!
服务端接收数据:Ouch!
服务端接收数据:I am king of the world!
服务端接收数据:Ouch!
服务端接收数据:I am king of the world!
服务端接收数据:Ouch!

笔记本上的ROS客户端

redwall@redwall-G3-3500:~$ rosrun joystick_client joystick_client 
[ERROR] [1656939307.244367879]: [registerPublisher] Failed to contact master at [localhost:11311].  Retrying...
[ INFO] [1656939314.923909682]: Connected to master at [localhost:11311]
vel X:0;vel Y:0;angular Z:0
接收服务端报文:I am your father!

vel X:0;vel Y:0;angular Z:0
接收服务端报文:I am your father!

vel X:0;vel Y:0;angular Z:0
接收服务端报文:I am your father!

虚拟机的普通客户端

  • prejudice@prejudice-VirtualBox:~/socket_test/socket_for_linux/bin$ ./tcp_client 成功连接服务器!

  • 接收服务端报文:I am your father!

  • 接收服务端报文:I am your father!

  • 接收服务端报文:I am your father!

“怎么使用C++ Thread实现简单的socket多线程通信”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么使用C++ Thread实现简单的socket多线程通信

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么使用C++ Thread实现简单的socket多线程通信

本篇内容介绍了“怎么使用C++ Thread实现简单的socket多线程通信”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!服务端多线程功能放
2023-07-02

php怎么使用socket简单实现通信功能

这篇文章主要讲解了“php怎么使用socket简单实现通信功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php怎么使用socket简单实现通信功能”吧!WebSocket的作用WebSo
2023-07-05

Java中的单线程通信如何利用 Socket实现

这期内容当中小编将会给大家带来有关Java中的单线程通信如何利用 Socket实现,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java Socket实现单线程通信的方法,具体如下:现在做Java直接使用
2023-05-31

Java项目中的多线程通信如何利用Socket实现

这期内容当中小编将会给大家带来有关Java项目中的多线程通信如何利用Socket实现,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java Socket实现多线程通信的方法,代码如下:package co
2023-05-31

C++怎么实现一个简单的线程池

本文小编为大家详细介绍“C++怎么实现一个简单的线程池”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现一个简单的线程池”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、设计线程池应该包括保存线程的容
2023-06-30

怎么在c#中利用委托事件实现多线程通信

本篇文章为大家展示了怎么在c#中利用委托事件实现多线程通信,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。在研究c# 线程之间通信时,发现传统的方法大概有三种:全局变量,由于同一进程下的多个进程之间共
2023-06-14

怎么使用Java socket通信模拟QQ实现多人聊天室

这篇文章主要介绍“怎么使用Java socket通信模拟QQ实现多人聊天室”,在日常操作中,相信很多人在怎么使用Java socket通信模拟QQ实现多人聊天室问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎
2023-07-02

Java怎么使用wait或notify实现线程间通信

这篇文章主要介绍“Java怎么使用wait或notify实现线程间通信”,在日常操作中,相信很多人在Java怎么使用wait或notify实现线程间通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎
2023-07-04

Java中怎么使用wait和notify实现线程间的通信

这篇“Java中怎么使用wait和notify实现线程间的通信”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中怎么使
2023-06-30

怎么用Python实现简单的C++程序范围

本篇内容主要讲解“怎么用Python实现简单的C++程序范围”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用Python实现简单的C++程序范围”吧!1. 实验说明问题要求:针对静态单赋值(
2023-06-29

怎么使用JavaScript实现一个简单的通讯录

这篇文章主要介绍“怎么使用JavaScript实现一个简单的通讯录”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用JavaScript实现一个简单的通讯录”文章能帮助大家解决问题。1.创建通讯
2023-07-06

Java中的多线程回显服务器怎么利用Socket实现

Java中的多线程回显服务器怎么利用Socket实现?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。具体如下:需要两个类,一个是EchoServer,代表服务器。另外一个是Ech
2023-05-31

怎么使用C#实现简单的计算器功能

这篇文章主要介绍怎么使用C#实现简单的计算器功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!环境:VS2010及以上版本1、建立个Window窗体应用2、在工具箱里拖出两个TextBox,第一个放上面,第二个放下面
2023-06-29

怎么用C#实现简单的计算器小程序

这篇文章主要介绍“怎么用C#实现简单的计算器小程序”,在日常操作中,相信很多人在怎么用C#实现简单的计算器小程序问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用C#实现简单的计算器小程序”的疑惑有所帮助!
2023-06-29

Java中使用Thread类和Runnable接口实现多线程的区别是什么

这篇“Java中使用Thread类和Runnable接口实现多线程的区别是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“
2023-07-02

python怎么使用SimpleXMLRPCServer实现简单的rpc过程

这篇文章主要介绍了python怎么使用SimpleXMLRPCServer实现简单的rpc过程的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇python怎么使用SimpleXMLRPCServer实现简单的rp
2023-07-02

怎么使用jQuery实现简单的流程显示

这篇文章主要介绍了怎么使用jQuery实现简单的流程显示的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用jQuery实现简单的流程显示文章都会有所收获,下面我们一起来看看吧。jQuery是一个非常流行的J
2023-07-05

怎么在c#中使用Parallelx实现并行和多线程编程

本篇文章给大家分享的是有关怎么在c#中使用Parallelx实现并行和多线程编程,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、 Parallel的使用1、Parallel.
2023-06-06

Android中的多进程通信怎么利用继承Binder类实现

Android中的多进程通信怎么利用继承Binder类实现?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。服务端代码,BinderService.java:首先继
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录