网站推广外包公司哪家好,做网站推广的,房屋在线设计平台,惠州的企业网站建设文章目录 概要样例代码 概要
当第一次运行服务端时正常#xff0c;第二次运行时出现Bind failed问题。
在实际使用中#xff0c;如果您尝试启动一个服务端程序并且遇到了 “Bind failed” 的错误信息#xff0c;这通常意味着尝试绑定#xff08;bind#xff09;的端口已… 文章目录 概要样例代码 概要
当第一次运行服务端时正常第二次运行时出现Bind failed问题。
在实际使用中如果您尝试启动一个服务端程序并且遇到了 “Bind failed” 的错误信息这通常意味着尝试绑定bind的端口已经被占用。这种情况可能有以下几个常见原因 端口占用如果之前启动的服务端实例没有正确关闭或者其他程序正在使用相同的端口那么操作系统将不允许您再次绑定到该端口。 未正确释放端口在服务端程序异常退出或者没有正确关闭套接字的情况下操作系统可能仍然认为端口正在被使用。 TIME_WAIT状态即使服务端正确关闭了套接字TCP端口可能会因为TIME_WAIT状态而暂时不可用。TIME_WAIT是TCP连接正常关闭后的一个保留状态用于确保所有的数据包都正确地完成传输。这个状态通常会持续一段时间通常是几分钟。 系统安全策略某些操作系统可能有安全策略限制了对低端口号通常是1024以下的访问。这通常会要求服务端程序以管理员或特权用户身份运行。
为了解决 “Bind failed” 的问题您可以采取以下几个步骤 检查端口使用情况在Unix-like系统中可以使用 lsof -i :端口号 或 netstat -tulnp | grep 端口号 命令来检查端口占用情况。在Windows系统中可以使用 netstat -aon | findstr 端口号。 确保正确关闭套接字在您的代码中确保在服务端关闭时您调用了套接字的关闭方法。 设置SO_REUSEADDR套接字选项这个选项允许重新绑定到正在TIME_WAIT状态的端口。在C/C中这可以通过设置套接字选项来完成
int yes 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, yes, sizeof(yes)) -1) {// 错误处理更改端口号尝试使用另一个未被占用的端口号。 检查权限确保您的程序有足够的权限来绑定所需的端口。 重启系统如果以上方法都无法解决问题重启系统可以清除所有占用的端口并重置网络堆栈。
样例代码
头文件
#include ros/ros.h
#include std_msgs/String.h
#include std_msgs/Bool.h
#include iostream
#include cstring
#include unistd.h
#include arpa/inet.h
#include sys/socket.h
#include geometry_msgs/Twist.h
#include threadusing namespace std;class TCPPublisher
{public:TCPPublisher();~TCPPublisher();void cmdVelCallback(const geometry_msgs::Twist::ConstPtr msg);void acceptClients();void sendToAllClients(const std::string message);private:ros::NodeHandle n, nPrivate;ros::Publisher tcpPub;ros::Subscriber cmdVelSub;// 创建服务器套接字int serverSocket;// 设置服务器地址结构sockaddr_in serverAddr;std::vectorint clientSockets;std::mutex clientSocketsMutex;int clientSocket;std::string topicStatus;std::thread acceptThread;
};main.cpp
#include ./tcp_pub/tcp_pub.hTCPPublisher::TCPPublisher():nPrivate(~)
{nPrivate.param(topicStatus, topicStatus, std::string(/cmd_vel));// 创建套接字serverSocket socket(AF_INET, SOCK_STREAM, 0);// 设置套接字选项允许重新使用本地地址和端口int yes 1;if (setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, yes, sizeof(yes)) -1) {std::cerr Setsockopt failed. std::endl;close(serverSocket);return;}/*订阅话题*/cmdVelSub n.subscribe(topicStatus.c_str(), 10, TCPPublisher::cmdVelCallback, this);// 设置服务器地址结构sockaddr_in serverAddr;serverAddr.sin_family AF_INET;serverAddr.sin_addr.s_addr INADDR_ANY;serverAddr.sin_port htons(8080); // 服务器监听的端口号// 绑定套接字if (bind(serverSocket, (struct sockaddr*)serverAddr, sizeof(serverAddr)) -1) {std::cerr Bind failed. std::endl;close(serverSocket);return;}// 监听连接if (listen(serverSocket, SOMAXCONN) -1) {std::cerr Listen failed. std::endl;close(serverSocket);return;}std::cout Server is listening for incoming connections... std::endl;// 在新线程中接受客户端连接acceptThread std::thread(TCPPublisher::acceptClients, this);ROS_INFO(TCPPublisher init successfully!!!);
}TCPPublisher::~TCPPublisher()
{close(serverSocket);
}void TCPPublisher::cmdVelCallback(const geometry_msgs::Twist::ConstPtr msg)
{float velX msg-linear.x;float angularZ msg-angular.z;// ROS_INFO(velX : %f, angularZ : %f, velX, angularZ);// 定义字符数组用于存储转换后的结果char buffer[50]; // 适当调整数组大小以适应你的需求snprintf(buffer, sizeof(buffer), %f,%f, velX, angularZ);// ROS_INFO(buffer %s, buffer);std::ostringstream ss;ss velX , angularZ;sendToAllClients(ss.str());
}void TCPPublisher::acceptClients() {while (ros::ok()) {int clientSocket accept(serverSocket, NULL, NULL);if (clientSocket -1) {std::cerr Accept failed. std::endl;continue;}std::cout Connection established with a client. std::endl;// 添加到客户端列表std::lock_guardstd::mutex guard(clientSocketsMutex);clientSockets.push_back(clientSocket);}
}void TCPPublisher::sendToAllClients(const std::string message) {std::lock_guardstd::mutex guard(clientSocketsMutex);for (auto it clientSockets.begin(); it ! clientSockets.end(); ) {if (send(*it, message.c_str(), message.size(), 0) -1) {std::cerr Error sending message to client. std::endl;close(*it);it clientSockets.erase(it); // Remove from list if send fails} else {it;}}
}int main(int argc, char **argv) {//创建节点ros::init(argc, argv, pure_pursuit);TCPPublisher tp; ros::spin();return 0;
}