最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ Thread實(shí)現(xiàn)簡(jiǎn)單的socket多線(xiàn)程通信

 更新時(shí)間:2022年07月05日 11:28:57   作者:合工大機(jī)器人實(shí)驗(yàn)室  
本文主要介紹了C++ Thread實(shí)現(xiàn)簡(jiǎn)單的socket多線(xiàn)程通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

起因

為什么要用C++的Thread,很簡(jiǎn)單,因?yàn)槲也?/p>

一打五用pthread實(shí)現(xiàn)了socket多線(xiàn)程通信,我之前學(xué)并發(fā)的時(shí)候沒(méi)看pthread,因此代碼只能看個(gè)大概,后面還是要系統(tǒng)學(xué)一下pthread的

服務(wù)端

多線(xiàn)程功能放在騰訊云服務(wù)器上,代碼如下:

#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 << "服務(wù)端初始化失敗?。?" << 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 << "接收客戶(hù)端數(shù)據(jù)失??!" << endl;
? ? ? ? ? ? tcplck.unlock();
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? cout << "服務(wù)端接收數(shù)據(jù):" << buffer << endl;

? ? ? ? strcpy(buffer, "I am your father!");
? ? ? ? if (!server.tcpSend(clientfd, buffer, sizeof(buffer)))
? ? ? ? {
? ? ? ? ? ? cout << "向客戶(hù)端發(fā)送數(shù)據(jù)失?。? << endl;
? ? ? ? ? ? tcplck.unlock();
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? tcplck.unlock();
?? ??? ??? ??? ?usleep(100);
? ? }
? ? cout << "通信異常!" << endl;
? ? return;
}

實(shí)在是很簡(jiǎn)單,貽笑大方了

有幾個(gè)注意點(diǎn):

  • 全局變量在main函數(shù)執(zhí)行完后會(huì)銷(xiāo)毀,線(xiàn)程中用到了全局變量server,線(xiàn)程detach后要保證數(shù)據(jù)的收發(fā),就要保持server的生存期,這里體現(xiàn)為在main中循環(huán)等待客戶(hù)端的連接
  • 要用鎖鎖住線(xiàn)程中server的操作,避免不同線(xiàn)程同時(shí)操作server造成混亂
  • usleep(100);是為了避免不同線(xiàn)程爭(zhēng)搶同一把鎖而造成死鎖的發(fā)生

ROS客戶(hù)端

#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 << "向服務(wù)端發(fā)送報(bào)文失?。? << endl;
? ? }
? ? if (!client.tcpRecv(client.m_sockfd, recv_buff, NULL, 10))
? ? {
? ? ? ? cout << "從服務(wù)端接收?qǐng)?bào)文失?。? << endl;
? ? }
? ? cout << "接收服務(wù)端報(bào)文:" << 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();
}

很簡(jiǎn)單,訂閱了手柄發(fā)布的話(huà)題/cmd_vel,在回調(diào)函數(shù)中和服務(wù)端通訊

話(huà)題的發(fā)布頻率是10Hz,意味著和服務(wù)端通訊的頻率也是10Hz

普通客戶(hù)端

#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 << "成功連接服務(wù)器!" << endl;

? ? char buff[1024];
? ? while (true)
? ? {
? ? ? ? memset(buff, 0, sizeof(buff));
? ? ? ? sprintf(buff, "Ouch!");
? ? ? ? if (!client.tcpSend(client.m_sockfd, buff, sizeof(buff)))
? ? ? ? {
? ? ? ? ? ? cout << "向服務(wù)端發(fā)送報(bào)文失??!" << endl;
? ? ? ? ? ? return -1;
? ? ? ? }

? ? ? ? memset(buff, 0, sizeof(buff));
? ? ? ? if (!client.tcpRecv(client.m_sockfd, buff, NULL, 5))
? ? ? ? {
? ? ? ? ? ? cout << "從服務(wù)端接收?qǐng)?bào)文失??!" << endl;
? ? ? ? ? ? return -1;
? ? ? ? }
? ? ? ? cout << "接收服務(wù)端報(bào)文:" << buff << endl << endl;
? ? ? ? sleep(0.1);
? ? }
? ? return 0;
}

這里sleep(0.1);是為了模擬ROS中話(huà)題的頻率

sleep過(guò)長(zhǎng)會(huì)導(dǎo)致服務(wù)端阻塞等待該客戶(hù)端的消息,從而導(dǎo)致其余客戶(hù)端與服務(wù)端的通信失敗(如果客戶(hù)端中允許的通信延時(shí)很短的話(huà))

運(yùn)行效果

云服務(wù)器上的服務(wù)端

[root@VM-4-11-centos bin]# ./server_thread 
Tcp thread 140662362572544 is joinable!
服務(wù)端接收數(shù)據(jù):I am king of the world!
服務(wù)端接收數(shù)據(jù):I am king of the world!
服務(wù)端接收數(shù)據(jù):I am king of the world!
服務(wù)端接收數(shù)據(jù):I am king of the world!
Tcp thread 140662354179840 is joinable!
服務(wù)端接收數(shù)據(jù):I am king of the world!
服務(wù)端接收數(shù)據(jù):Ouch!
服務(wù)端接收數(shù)據(jù):I am king of the world!
服務(wù)端接收數(shù)據(jù):Ouch!
服務(wù)端接收數(shù)據(jù):I am king of the world!
服務(wù)端接收數(shù)據(jù):Ouch!
服務(wù)端接收數(shù)據(jù):I am king of the world!
服務(wù)端接收數(shù)據(jù):Ouch!

筆記本上的ROS客戶(hù)端

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
接收服務(wù)端報(bào)文:I am your father!

vel X:0;vel Y:0;angular Z:0
接收服務(wù)端報(bào)文:I am your father!

vel X:0;vel Y:0;angular Z:0
接收服務(wù)端報(bào)文:I am your father!

虛擬機(jī)的普通客戶(hù)端

  • prejudice@prejudice-VirtualBox:~/socket_test/socket_for_linux/bin$ ./tcp_client 成功連接服務(wù)器!
  • 接收服務(wù)端報(bào)文:I am your father!
  • 接收服務(wù)端報(bào)文:I am your father!
  • 接收服務(wù)端報(bào)文:I am your father!

不足

  • 未考慮線(xiàn)程的清理
  • 未考慮信號(hào)的退出處理

 到此這篇關(guān)于C++ Thread實(shí)現(xiàn)簡(jiǎn)單的socket多線(xiàn)程通信的文章就介紹到這了,更多相關(guān)C++  socket多線(xiàn)程通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中的memset用法詳解

    C++中的memset用法詳解

    memset是一個(gè)初始化函數(shù),作用是將某一塊內(nèi)存中的全部設(shè)置為指定的值,本文給大家介紹C++中的memset用法,感興趣的朋友跟隨小編一起看看吧
    2023-02-02
  • 使用c++實(shí)現(xiàn)OpenCV繪制圓端矩形

    使用c++實(shí)現(xiàn)OpenCV繪制圓端矩形

    這篇文章主要介紹了使用c++實(shí)現(xiàn)OpenCV繪制圓端矩形,其中著重的講解了OpenCV使用過(guò)程中需要注意的一些小細(xì)節(jié),避免浪費(fèi)大家在開(kāi)發(fā)過(guò)程中浪費(fèi)多余的時(shí)間
    2021-08-08
  • C++?RBTree紅黑樹(shù)的性質(zhì)與實(shí)現(xiàn)

    C++?RBTree紅黑樹(shù)的性質(zhì)與實(shí)現(xiàn)

    紅黑樹(shù)是一種二叉搜索樹(shù),但在每個(gè)結(jié)點(diǎn)上增加一個(gè)存儲(chǔ)位表示結(jié)點(diǎn)的顏色,可以是Red或Black;通過(guò)對(duì)任何一條從根到葉子的路徑上各個(gè)結(jié)點(diǎn)著色方式的限制,紅黑樹(shù)確保沒(méi)有一條路徑會(huì)比其他路徑長(zhǎng)出倆倍,因而是平衡的
    2023-03-03
  • 簡(jiǎn)要對(duì)比C語(yǔ)言中的truncate()函數(shù)與ftruncate()函數(shù)

    簡(jiǎn)要對(duì)比C語(yǔ)言中的truncate()函數(shù)與ftruncate()函數(shù)

    這篇文章主要介紹了C語(yǔ)言中的truncate()函數(shù)與ftruncate()函數(shù)的簡(jiǎn)要對(duì)比,注意其之間的區(qū)別,需要的朋友可以參考下
    2015-09-09
  • C語(yǔ)言實(shí)現(xiàn)最全自動(dòng)售貨機(jī)

    C語(yǔ)言實(shí)現(xiàn)最全自動(dòng)售貨機(jī)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)最全自動(dòng)售貨機(jī),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C語(yǔ)言中的初階指針詳解

    C語(yǔ)言中的初階指針詳解

    這篇文章主要介紹了C語(yǔ)言中的初階指針,介紹了其相關(guān)概念,具有一定參考價(jià)值。需要的朋友可以了解下,希望能夠給你帶來(lái)幫助
    2021-10-10
  • C++入門(mén)指南之貪吃蛇游戲的實(shí)現(xiàn)

    C++入門(mén)指南之貪吃蛇游戲的實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于C++入門(mén)指南之貪吃蛇游戲?qū)崿F(xiàn)的相關(guān)資料,文章通過(guò)示例代碼介紹的非常詳細(xì),可以讓大家能短時(shí)間內(nèi)寫(xiě)出一個(gè)貪吃蛇,需要的朋友可以參考下
    2021-10-10
  • C語(yǔ)言字符函數(shù)、內(nèi)存函數(shù)功能及實(shí)現(xiàn)代碼

    C語(yǔ)言字符函數(shù)、內(nèi)存函數(shù)功能及實(shí)現(xiàn)代碼

    這篇文章主要介紹了C語(yǔ)言字符函數(shù)、內(nèi)存函數(shù) 功能及實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • linux中查詢(xún)dns示例

    linux中查詢(xún)dns示例

    這篇文章主要介紹了linux中查詢(xún)dns示例,需要的朋友可以參考下
    2014-04-04
  • FFmpeg實(shí)戰(zhàn)之分離出PCM數(shù)據(jù)

    FFmpeg實(shí)戰(zhàn)之分離出PCM數(shù)據(jù)

    PCM(Pulse?Code?Modulation,脈沖編碼調(diào)制)音頻數(shù)據(jù)是未經(jīng)壓縮的音頻采樣數(shù)據(jù)裸流,它是由模擬信號(hào)經(jīng)過(guò)采樣、量化、編碼轉(zhuǎn)換成的標(biāo)準(zhǔn)數(shù)字音頻數(shù)據(jù)。本文將通過(guò)FFmpeg實(shí)現(xiàn)分離PCM數(shù)據(jù),感興趣的可以了解一下
    2023-02-02

最新評(píng)論

陕西省| 临城县| 上饶县| 辽阳县| 苍梧县| 湖南省| 鹤山市| 邛崃市| 海晏县| 宾阳县| 得荣县| 平陆县| 治县。| 巢湖市| 奇台县| 张掖市| 平阴县| 乐昌市| 区。| 峡江县| 保康县| 城固县| 景泰县| 新兴县| 潢川县| 英德市| 商南县| 焦作市| 麻栗坡县| 贵定县| 江门市| 漳浦县| 河北省| 泸水县| 将乐县| 马尔康县| 马鞍山市| 永年县| 沙雅县| 马公市| 尚志市|