当前位置:   article > 正文

Socket 学习 3_server socket(af_inet, sock_stream, ipproto_tcp))

server socket(af_inet, sock_stream, ipproto_tcp)) client

Socket通信学习 (自用笔记)

三、结合前两次的实验,实现linux和windoes下的socket通信

1.跨系统通信;并且结合ROS下的话题通信,在收到相关话题后,通过socket向windows下的服务端发送指定的信息

3.代码

server.cpp (windows)

  1. #include<WinSock2.h>
  2. #include<iostream>
  3. #include<string>
  4. using namespace std;
  5. #pragma comment(lib,"ws2_32.lib")
  6. int main(int arg, char* argv[])
  7. {
  8. cout << "Socket服务端" << endl;
  9. //初始化DLL
  10. WORD sockVersion = MAKEWORD(2, 2);
  11. WSADATA wsdata;
  12. if (WSAStartup(sockVersion, &wsdata) != 0)
  13. {
  14. return 1;
  15. }
  16. //创建套接字
  17. SOCKET serversocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  18. //绑定套接字
  19. sockaddr_in server_addr;
  20. server_addr.sin_family = AF_INET;
  21. server_addr.sin_port = htons(10000);
  22. server_addr.sin_addr.S_un.S_addr = INADDR_ANY;
  23. bind(serversocket, (sockaddr*)&server_addr, sizeof(server_addr));
  24. //建立通信套接字标识符
  25. SOCKET clientsocket;
  26. sockaddr_in client_addr;
  27. int len = sizeof(client_addr);
  28. while (true)
  29. {
  30. if (listen(serversocket, 5) == SOCKET_ERROR)
  31. {
  32. cout << "Bind Error" << endl;
  33. break;
  34. }
  35. //建立连接
  36. clientsocket = accept(serversocket, (sockaddr*)&client_addr, &len);
  37. if (clientsocket != INVALID_SOCKET)
  38. {
  39. cout << "连接到:" << inet_ntoa(client_addr.sin_addr) << endl;
  40. }
  41. //进入接收消息循环
  42. char msg[100];//接收消息缓冲区
  43. string check;
  44. check = "a";
  45. const char *ch;
  46. ch = check.c_str();
  47. while (true)
  48. {
  49. int num = recv(clientsocket, msg, 100, 0);
  50. if (num > 0)
  51. {
  52. msg[num] = '\0';
  53. cout << "客户端:" << msg << endl;
  54. send(clientsocket, ch, strlen(ch), 0);
  55. }
  56. else
  57. {
  58. break;
  59. }
  60. }
  61. }
  62. closesocket(clientsocket);
  63. closesocket(serversocket);
  64. WSACleanup();
  65. return 0;
  66. }

client.cpp (ubuntu)

  1. #include <ros/ros.h>
  2. #include <std_msgs/String.h>
  3. #include <arpa/inet.h>
  4. #include <sys/socket.h>
  5. #include <string>
  6. #include <iostream>
  7. #include <unistd.h>
  8. using namespace std;
  9. #define port 10000
  10. const char* _ip;
  11. int clientsocket;
  12. int i=0;
  13. sockaddr_in client_addr;
  14. string order="ok";
  15. void chatterCallback(const std_msgs::String::ConstPtr& msg)
  16. {
  17. ROS_INFO("listener is receiving [%s]", msg->data.c_str());
  18. //发送指令
  19. send (clientsocket,(char*)order.c_str(),order.length(),0);
  20. }
  21. int main (int argc,char **argv)
  22. {
  23. cout<<"socket客户端"<<endl;
  24. cout <<"请输入主机ip地址:"<<endl;
  25. string ip;
  26. cin>>ip;
  27. _ip=ip.c_str();
  28. //创建套接字
  29. clientsocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  30. client_addr.sin_family=AF_INET;
  31. client_addr.sin_port=htons(port);
  32. client_addr.sin_addr.s_addr=inet_addr(_ip);
  33. int check=connect(clientsocket,(sockaddr*)&client_addr,sizeof(client_addr));
  34. if(check<0)
  35. {
  36. cout<<"连接失败"<<endl;
  37. cout<<"请先开启服务器"<<endl;
  38. }
  39. else
  40. {
  41. cout<<"连接成功"<<endl;
  42. }
  43. //初始化节点
  44. ros::init(argc,argv,"listener");
  45. ros::NodeHandle n;
  46. //创建订阅者
  47. ros::Subscriber sub=n.subscribe("chatter", 1000, chatterCallback);
  48. ros::spin(); //程序进入循环,直到ros::ok()返回false,进程结束。
  49. close(clientsocket);
  50. return 0;
  51. }

以上订阅的“chatter”话题,时自己写的一个实验话题,只是发送一段字符串

talker.cpp

  1. #include <iostream>
  2. #include "ros/ros.h"
  3. #include "std_msgs/String.h"
  4. int main(int argc, char **argv)
  5. {
  6. //ros节点初始化 "talker"节点名称,在ROS里同一时间不允许出现两个
  7. ros::init(argc,argv,"talker");
  8. //创建节点句柄
  9. ros::NodeHandle h;
  10. //创建一个publisher, topic:chatter,消息类型std_msgs::String
  11. ros::Publisher chatter_pub = h.advertise<std_msgs::String>("chatter",1000); // "chatter"话题名称,消息缓存
  12. //设置单循环的频率
  13. ros::Rate looprate(0.5);
  14. while (ros::ok())
  15. {
  16. std_msgs::String msg;
  17. std::stringstream ss;
  18. ss<<"zzzzzzzz";
  19. msg.data = ss.str();
  20. //发布消息
  21. ROS_INFO("%s",msg.data.c_str());
  22. chatter_pub.publish(msg);
  23. //等待回调函数
  24. ros::spinOnce();
  25. //按照之前设定的进行循环
  26. looprate.sleep();
  27. }
  28. }

4.出现的问题,服务器中的listern()和accept()写在循环中,但是client中的connect写在循环外,最后导致只能收发一次,一直以为是client中的send()函数存在问题,最后检查send()函数的返回值才发现,是服务器的问题。以后调试代码时,要记得检查函数的返回值来判断问题。

5.以上实验成功后,将订阅的话题更改为turtlebot2中的到达目标点,来达到最终的目标

movebase_socket.cpp

  1. #include <ros/ros.h>
  2. #include <std_msgs/String.h>
  3. #include <arpa/inet.h>
  4. #include <sys/socket.h>
  5. #include <string>
  6. #include <iostream>
  7. #include <unistd.h>
  8. #include <move_base_msgs/MoveBaseAction.h>
  9. #include <move_base_msgs/MoveBaseActionGoal.h>
  10. using namespace std;
  11. #define port 10000
  12. const char* _ip;
  13. int clientsocket;
  14. int i=0;
  15. sockaddr_in client_addr;
  16. string order="ok";
  17. void chatterCallback(const move_base_msgs::MoveBaseActionResult& msg)
  18. {
  19. //发送指令
  20. if (msg.status.status==3)
  21. {
  22. cout <<"到达目标点"<<endl;
  23. send (clientsocket,(char*)order.c_str(),order.length(),0);
  24. }
  25. }
  26. int main (int argc,char **argv)
  27. {
  28. cout<<"socket客户端"<<endl;
  29. cout <<"请输入主机ip地址:"<<endl;
  30. string ip;
  31. cin>>ip;
  32. _ip=ip.c_str();
  33. //创建套接字
  34. clientsocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  35. client_addr.sin_family=AF_INET;
  36. client_addr.sin_port=htons(port);
  37. client_addr.sin_addr.s_addr=inet_addr(_ip);
  38. int check=connect(clientsocket,(sockaddr*)&client_addr,sizeof(client_addr));
  39. if(check<0)
  40. {
  41. cout<<"连接失败"<<endl;
  42. cout<<"请先开启服务器"<<endl;
  43. }
  44. else
  45. {
  46. cout<<"连接成功"<<endl;
  47. }
  48. //初始化节点
  49. ros::init(argc,argv,"get_status");
  50. ros::NodeHandle n;
  51. //创建订阅者
  52. ros::Subscriber sub=n.subscribe("move_base/result", 10, chatterCallback);
  53. ros::spin(); //程序进入循环,直到ros::ok()返回false,进程结束。
  54. close(clientsocket);
  55. return 0;
  56. }

订阅“move_base/result”话题,消息类型为move_base_msgs/MoveBaseActionResult

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/147189
推荐阅读
相关标签
  

闽ICP备14008679号