- ROS-I simple_message 源码分析:UdpSer
- ROS-I simple_message 源码分析:Messag
- ROS-I simple_message 源码分析:SmplMs
- ROS-I simple_message 源码分析:Messag
- ROS-I simple_message 源码分析:JointT
- ROS-I simple_message 源码分析:JointT
- ROS-I simple_message 源码分析:JointT
- ROS-I simple_message 源码分析:TypedM
- ROS-I simple_message 源码分析:RobotS
- ROS-I simple_message 源码分析:JointT
udp_server类实现的是一个UDP服务器,继承自UdpSocket
namespace industrial
{
namespace udp_server
{
class UdpServer : public industrial::udp_socket::UdpSocket
{
public:
UdpServer();
~UdpServer();
bool makeConnect();
bool init(int port_num);
};
init
bool UdpServer::init(int port_num)
{
int rc = this->SOCKET_FAIL;
bool rtn;
SOCKLEN_T addrSize = 0;
/* 创建socket:
* AF_INET - IPv4 协议
* SOCK_DGRAM - UDP 类型
* protocol (0) - 采用默认
*/
rc = SOCKET(AF_INET, SOCK_DGRAM, 0);
if (this->SOCKET_FAIL != rc)
{
this->setSockHandle(rc);
LOG_DEBUG("Socket created, rc: %d", rc);
LOG_DEBUG("Socket handle: %d", this->getSockHandle());
// Initialize address data structure
memset(&this->sockaddr_, 0, sizeof(this->sockaddr_));
this->sockaddr_.sin_family = AF_INET;
this->sockaddr_.sin_addr.s_addr = INADDR_ANY;
this->sockaddr_.sin_port = HTONS(port_num);
addrSize = sizeof(this->sockaddr_);
rc = BIND(this->getSockHandle(), (sockaddr *)&(this->sockaddr_), addrSize);
if (this->SOCKET_FAIL != rc)
{
rtn = true;
LOG_INFO("Server socket successfully initialized");
}
else
{
LOG_ERROR("Failed to bind socket, rc: %d", rc);
CLOSE(this->getSockHandle());
rtn = false;
}
}
else
{
LOG_ERROR("Failed to create socket, rc: %d", rc);
rtn = false;
}
return rtn;
}
初始化过程和TcpServer类似,依次调用socket,bind,但无需进入监听状态。
makeConnect
bool UdpServer::makeConnect()
{
ByteArray send;
char sendHS = this->CONNECT_HANDSHAKE;
char recvHS = 0;
int bytesRcvd = 0;
const int timeout = 1000; // Time (ms) between handshake sends
bool rtn = false;
send.load((void*)&sendHS, sizeof(sendHS));
if (!this->isConnected())
{
this->setConnected(false);
// 循环,监听握手号
do
{
ByteArray recv;
recvHS = 0;
if (this->isReadyReceive(timeout))
{
bytesRcvd = this->rawReceiveBytes(this->buffer_, 0);
if (bytesRcvd > 0)
{
LOG_DEBUG("UDP server received %d bytes while waiting for handshake", bytesRcvd);
recv.init(&this->buffer_[0], bytesRcvd);
recv.unload((void*)&recvHS, sizeof(recvHS));
}
}
}
while(recvHS != sendHS);
const int sendLen = send.getBufferSize();
char localBuffer[sendLen];
send.unload(localBuffer, sendLen);
// 回复握手号
this->rawSendBytes(localBuffer, sendLen);
this->setConnected(true);
rtn = true;
}
else
{
LOG_WARN("Tried to connect when socket already in connected state");
rtn = true;
}
return rtn;
}
调用makeConnect后,若当前没有连接,服务器会进入循环,尝试接收客户端发送握手号,接收到握手号后服务器则回复相同的握手号。
网友评论