TcpClient同样继承自TcpSocket类,完成的是TCP客户端的功能。
namespace industrial
{
namespace tcp_client
{
class TcpClient : public industrial::tcp_socket::TcpSocket
{
public:
TcpClient();
~TcpClient();
bool init(char *buff, int port_num);
// Overrides
bool makeConnect();
};
} //tcp_client
} //industrial
init
bool TcpClient::init(char *buff, int port_num)
{
int rc;
bool rtn;
int disableNodeDelay = 1;
addrinfo *result;
addrinfo hints = {};
rc = SOCKET(AF_INET, SOCK_STREAM, 0);
if (this->SOCKET_FAIL != rc)
{
this->setSockHandle(rc);
// The set no delay disables the NAGEL algorithm
rc = SET_NO_DELAY(this->getSockHandle(), disableNodeDelay);
if (this->SOCKET_FAIL == rc)
{
LOG_WARN("Failed to set no socket delay, sending data can be delayed by up to 250ms");
}
// Initialize address data structure
memset(&this->sockaddr_, 0, sizeof(this->sockaddr_));
this->sockaddr_.sin_family = AF_INET;
// Check for 'buff' as hostname, and use that, otherwise assume IP address
hints.ai_family = AF_INET; // Allow IPv4
hints.ai_socktype = SOCK_STREAM; // TCP socket
hints.ai_flags = 0; // No flags
hints.ai_protocol = 0; // Any protocol
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
if (0 == GETADDRINFO(buff, NULL, &hints, &result))
{
this->sockaddr_ = *((sockaddr_in *)result->ai_addr);
}
else
{
this->sockaddr_.sin_addr.s_addr = INET_ADDR(buff);
}
this->sockaddr_.sin_port = HTONS(port_num);
rtn = true;
}
else
{
LOG_ERROR("Failed to create socket, rc: %d", rc);
rtn = false;
}
return rtn;
}
以上为客户端初始化代码,主要是配置通信参数:禁用Nagle算法,转换IP地址,端口号至socket数据结构。
makeConnect
bool TcpClient::makeConnect()
{
bool rtn = false;
int rc = this->SOCKET_FAIL;
SOCKLEN_T addrSize = 0;
if (!this->isConnected())
{
addrSize = sizeof(this->sockaddr_);
rc = CONNECT(this->getSockHandle(), (sockaddr *)&this->sockaddr_, addrSize);
if (this->SOCKET_FAIL != rc)
{
LOG_INFO("Connected to server");
this->setConnected(true);
rtn = true;
}
else
{
this->logSocketError("Failed to connect to server", rc, errno);
rtn = false;
}
}
else
{
LOG_WARN("Tried to connect when socket already in connected state");
}
return rtn;
}
客户端的连接代码是简单的,调用connect尝试连接即可。
网友评论