1、获取HostInfo
get_host_info.h
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
bool getHostInfo(std::string& host_name, std::string& ip)
{
char name[256];
gethostname(name, sizeof(name));
host_name = name;
struct hostent* host = gethostbyname(name);
char ipStr[32];
const char* ret =
inet_ntop(host->h_addrtype, host->h_addr_list[0], ipStr, sizeof(ipStr));
if (NULL == ret) {
return false;
}
ip = ipStr;
return true;
};
2、服务端Server
#include <sys/socket.h>
#include <iostream>
#include "get_host_info.h"
int main()
{
int port = 9100;
std::string host_name,ip;
if(!getHostInfo(host_name,ip)){
return 0;
}
//创建套接字,绑定端口,IP
int server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(ip.c_str());
server_addr.sin_port = htons(port);
bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));
//进入监听状态,等待用户发起请求
if (listen(server_socket, 20)) {return 0;}
//在while循环内等待客户端的链接
struct sockaddr_in client_addr;
socklen_t client_addr_size = sizeof(client_addr);
while(true)
{
//接收到客户端套接字,server会持续停留在下面这条语句,直到接收到客户端
int client_sock = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_size);
//一次成功链接,考试处理作出反应
if (client_sock > 0)
{
std::string recv_buffer = "";
//一次成功链接后,会持续接受该客户端信息,直到客户端关闭,才会失去链接
while(1)
{
//注意client发过来的信息可能很长,会切割成1024大小的片段发送,所以需要多次接受
char buffer[1024];
memset(buffer,0,sizeof(buffer));
int len = recv(client_sock,buffer,sizeof(buffer),0);
if(len <= 0)break;
recv_buffer += std::string(buffer);
}
if(recv_buffer == ""){continue;}
//打印接收到的信息
std::cout<<"receive info : "<<recv_buffer<<std::endl;
//在这里也可以发送信息给client
}
close(client_sock);
}
close(server_socket);
return 0;
}
3、客户端Client
#include <sys/socket.h>
#include <iostream>
#include <ros/ros.h>
#include "get_host_info.h"
int main()
{
//切片发送字符串的lambda函数
auto sendString = [](int& socket, int step,std::string& send_str)
{
//计算待发送数据的长度
int len = strlen(send_str.c_str());
//发送数据
for (int i = 0; i < len; i = i + step) {
std::string str = send_str.substr(i, step);
send(socket, str.c_str(), strlen(str.c_str()), 0);
usleep(1);//中间需要有停顿,不可以一直发送,否则server接受会出现错乱
}
//发送一个空字符,server收到长度为0的字符后会停止接收
std::string str = "";
send(socket, str.c_str(), strlen(str.c_str()), 0);
};
//获取HostInfo
int port = 9100;
std::string host_name,ip;
if(!getHostInfo(host_name,ip)){return 0;}
//在while循环内持续创建套接字,并且发送信息
while (true) {
//创建客户端套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr(ip.c_str()); //具体的IP地址
serv_addr.sin_port = htons(port); //端口
//连接服务器
//connect只会链接一次,不会一直等待
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
//std::cout << "can not connect socket" << std::endl;
// exit(1);
} else {
//向server发送信息
//发送当前的wall time给服务端
ros::WallTime wall_time = ros::WallTime::now();
std::string str = std::to_string(wall_time.toSec());
sendString(sock, 1024, str);
}
close(sock);
sleep(1);
}
}