当前位置:网站首页>Tar source code analysis 6
Tar source code analysis 6
2022-07-04 06:37:00 【Tao song remains the same】
Students who like network programming , Don't miss it tars About China socket Part of , Let's take a look at the client operation .
It's really classic , have a look send/recv Well , Well written :
#include <cerrno>
#include <iostream>
#include "util/tc_clientsocket.h"
#include "util/tc_epoller.h"
#include "util/tc_common.h"
namespace tars
{
TC_Endpoint::TC_Endpoint()
{
_host = "0.0.0.0";
_port = 0;
_timeout = 3000;
_type = TCP;
_grid = 0;
_qos = 0;
_weight = -1;
_weighttype = 0;
_authType = 0;
}
void TC_Endpoint::init(const string& host, int port, int timeout, int type, int grid, int qos, int weight, unsigned int weighttype, int authType)
{
_host = host;
_port = port;
_timeout = timeout;
_type = type;
_grid = grid;
_qos = qos;
if (weighttype == 0)
{
_weight = -1;
_weighttype = 0;
}
else
{
if (weight == -1)
{
weight = 100;
}
_weight = (weight > 100 ? 100 : weight);
_weighttype = weighttype;
}
_authType = authType;
}
void TC_Endpoint::parse(const string &str)
{
_grid = 0;
_qos = 0;
_weight = -1;
_weighttype = 0;
_authType = 0;
const string delim = " \t\n\r";
string::size_type beg;
string::size_type end = 0;
beg = str.find_first_not_of(delim, end);
if(beg == string::npos)
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse error : " + str);
}
end = str.find_first_of(delim, beg);
if(end == string::npos)
{
end = str.length();
}
string desc = str.substr(beg, end - beg);
if(desc == "tcp")
{
_type = TCP;
}
else if (desc == "ssl")
{
_type = SSL;
}
else if(desc == "udp")
{
_type = UDP;
}
else
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse tcp or udp or ssl error : " + str);
}
desc = str.substr(end);
end = 0;
while(true)
{
beg = desc.find_first_not_of(delim, end);
if(beg == string::npos)
{
break;
}
end = desc.find_first_of(delim, beg);
if(end == string::npos)
{
end = desc.length();
}
string option = desc.substr(beg, end - beg);
if(option.length() != 2 || option[0] != '-')
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse error : " + str);
}
string argument;
string::size_type argumentBeg = desc.find_first_not_of(delim, end);
if(argumentBeg != string::npos && desc[argumentBeg] != '-')
{
beg = argumentBeg;
end = desc.find_first_of(delim, beg);
if(end == string::npos)
{
end = desc.length();
}
argument = desc.substr(beg, end - beg);
}
switch(option[1])
{
case 'h':
{
if(argument.empty())
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -h error : " + str);
}
const_cast<string&>(_host) = argument;
break;
}
case 'p':
{
istringstream p(argument);
if(!(p >> const_cast<int&>(_port)) || !p.eof() || _port < 0 || _port > 65535)
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -p error : " + str);
}
break;
}
case 't':
{
istringstream t(argument);
if(!(t >> const_cast<int&>(_timeout)) || !t.eof())
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -t error : " + str);
}
break;
}
case 'g':
{
istringstream t(argument);
if(!(t >> const_cast<int&>(_grid)) || !t.eof())
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -g error : " + str);
}
break;
}
case 'q':
{
istringstream t(argument);
if(!(t >> const_cast<int&>(_qos)) || !t.eof())
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -q error : " + str);
}
break;
}
case 'w':
{
istringstream t(argument);
if(!(t >> const_cast<int&>(_weight)) || !t.eof())
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -w error : " + str);
}
break;
}
case 'v':
{
istringstream t(argument);
if(!(t >> const_cast<unsigned int&>(_weighttype)) || !t.eof())
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -v error : " + str);
}
break;
}
// auth type
case 'e':
{
istringstream p(argument);
if (!(p >> const_cast<int&>(_authType)) || !p.eof() || _authType < 0 || _authType > 1)
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse -e error : " + str);
}
break;
}
default:
{
///throw TC_EndpointParse_Exception("TC_Endpoint::parse error : " + str);
}
}
}
if(_weighttype != 0)
{
if(_weight == -1)
{
_weight = 100;
}
_weight = (_weight > 100 ? 100 : _weight);
}
if(_host.empty())
{
throw TC_EndpointParse_Exception("TC_Endpoint::parse error : host must not be empty: " + str);
}
else if(_host == "*")
{
const_cast<string&>(_host) = "0.0.0.0";
}
if (_authType < 0)
_authType = 0;
else if (_authType > 0)
_authType = 1;
}
/*************************************TC_TCPClient**************************************/
#define LEN_MAXRECV 8196
int TC_TCPClient::checkSocket()
{
if(!_socket.isValid())
{
try
{
if(_port == 0)
{
_socket.createSocket(SOCK_STREAM, AF_LOCAL);
}
else
{
_socket.createSocket(SOCK_STREAM, AF_INET);
}
// Set non blocking mode
_socket.setblock(false);
try
{
if(_port == 0)
{
_socket.connect(_ip.c_str());
}
else
{
_socket.connect(_ip, _port);
}
}
catch(TC_SocketConnect_Exception &ex)
{
if(errno != EINPROGRESS)
{
_socket.close();
return EM_CONNECT;
}
}
if(errno != EINPROGRESS)
{
_socket.close();
return EM_CONNECT;
}
TC_Epoller epoller(false);
epoller.create(1);
epoller.add(_socket.getfd(), 0, EPOLLOUT);
int iRetCode = epoller.wait(_timeout);
if (iRetCode < 0)
{
_socket.close();
return EM_SELECT;
}
else if (iRetCode == 0)
{
_socket.close();
return EM_TIMEOUT;
}
else
{
for(int i = 0; i < iRetCode; ++i)
{
const epoll_event& ev = epoller.get(i);
if (ev.events & EPOLLERR || ev.events & EPOLLHUP)
{
_socket.close();
return EM_CONNECT;
}
else
{
int iVal = 0;
socklen_t iLen = static_cast<socklen_t>(sizeof(int));
if (::getsockopt(_socket.getfd(), SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&iVal), &iLen) == -1 || iVal)
{
_socket.close();
return EM_CONNECT;
}
}
}
}
// Set to blocking mode
_socket.setblock(true);
}
catch(TC_Socket_Exception &ex)
{
_socket.close();
return EM_SOCKET;
}
}
return EM_SUCCESS;
}
int TC_TCPClient::send(const char *sSendBuffer, size_t iSendLen)
{
int iRet = checkSocket();
if(iRet < 0)
{
return iRet;
}
iRet = _socket.send(sSendBuffer, iSendLen);
if(iRet < 0)
{
_socket.close();
return EM_SEND;
}
return EM_SUCCESS;
}
int TC_TCPClient::recv(char *sRecvBuffer, size_t &iRecvLen)
{
int iRet = checkSocket();
if(iRet < 0)
{
return iRet;
}
TC_Epoller epoller(false);
epoller.create(1);
epoller.add(_socket.getfd(), 0, EPOLLIN);
int iRetCode = epoller.wait(_timeout);
if (iRetCode < 0)
{
_socket.close();
return EM_SELECT;
}
else if (iRetCode == 0)
{
_socket.close();
return EM_TIMEOUT;
}
epoll_event ev = epoller.get(0);
if(ev.events & EPOLLIN)
{
int iLen = _socket.recv((void*)sRecvBuffer, iRecvLen);
if (iLen < 0)
{
_socket.close();
return EM_RECV;
}
else if (iLen == 0)
{
_socket.close();
return EM_CLOSE;
}
iRecvLen = iLen;
return EM_SUCCESS;
}
else
{
_socket.close();
}
return EM_SELECT;
}
int TC_TCPClient::recvBySep(string &sRecvBuffer, const string &sSep)
{
sRecvBuffer.clear();
int iRet = checkSocket();
if(iRet < 0)
{
return iRet;
}
TC_Epoller epoller(false);
epoller.create(1);
epoller.add(_socket.getfd(), 0, EPOLLIN);
while(true)
{
int iRetCode = epoller.wait(_timeout);
if (iRetCode < 0)
{
_socket.close();
return EM_SELECT;
}
else if (iRetCode == 0)
{
_socket.close();
return EM_TIMEOUT;
}
epoll_event ev = epoller.get(0);
if(ev.events & EPOLLIN)
{
char buffer[LEN_MAXRECV] = "\0";
int len = _socket.recv((void*)&buffer, sizeof(buffer));
if (len < 0)
{
_socket.close();
return EM_RECV;
}
else if (len == 0)
{
_socket.close();
return EM_CLOSE;
}
sRecvBuffer.append(buffer, len);
if(sRecvBuffer.length() >= sSep.length()
&& sRecvBuffer.compare(sRecvBuffer.length() - sSep.length(), sSep.length(), sSep) == 0)
{
break;
}
}
}
return EM_SUCCESS;
}
int TC_TCPClient::recvAll(string &sRecvBuffer)
{
sRecvBuffer.clear();
int iRet = checkSocket();
if(iRet < 0)
{
return iRet;
}
TC_Epoller epoller(false);
epoller.create(1);
epoller.add(_socket.getfd(), 0, EPOLLIN);
while(true)
{
int iRetCode = epoller.wait(_timeout);
if (iRetCode < 0)
{
_socket.close();
return EM_SELECT;
}
else if (iRetCode == 0)
{
_socket.close();
return EM_TIMEOUT;
}
epoll_event ev = epoller.get(0);
if(ev.events & EPOLLIN)
{
char sTmpBuffer[LEN_MAXRECV] = "\0";
int len = _socket.recv((void*)sTmpBuffer, LEN_MAXRECV);
if (len < 0)
{
_socket.close();
return EM_RECV;
}
else if (len == 0)
{
_socket.close();
return EM_SUCCESS;
}
sRecvBuffer.append(sTmpBuffer, len);
}
else
{
_socket.close();
return EM_SELECT;
}
}
return EM_SUCCESS;
}
int TC_TCPClient::recvLength(char *sRecvBuffer, size_t iRecvLen)
{
int iRet = checkSocket();
if(iRet < 0)
{
return iRet;
}
size_t iRecvLeft = iRecvLen;
iRecvLen = 0;
TC_Epoller epoller(false);
epoller.create(1);
epoller.add(_socket.getfd(), 0, EPOLLIN);
while(iRecvLeft != 0)
{
int iRetCode = epoller.wait(_timeout);
if (iRetCode < 0)
{
_socket.close();
return EM_SELECT;
}
else if (iRetCode == 0)
{
_socket.close();
return EM_TIMEOUT;
}
epoll_event ev = epoller.get(0);
if(ev.events & EPOLLIN)
{
int len = _socket.recv((void*)(sRecvBuffer + iRecvLen), iRecvLeft);
if (len < 0)
{
_socket.close();
return EM_RECV;
}
else if (len == 0)
{
_socket.close();
return EM_CLOSE;
}
iRecvLeft -= len;
iRecvLen += len;
}
else
{
_socket.close();
return EM_SELECT;
}
}
return EM_SUCCESS;
}
int TC_TCPClient::sendRecv(const char* sSendBuffer, size_t iSendLen, char *sRecvBuffer, size_t &iRecvLen)
{
int iRet = send(sSendBuffer, iSendLen);
if(iRet != EM_SUCCESS)
{
return iRet;
}
return recv(sRecvBuffer, iRecvLen);
}
int TC_TCPClient::sendRecvBySep(const char* sSendBuffer, size_t iSendLen, string &sRecvBuffer, const string &sSep)
{
int iRet = send(sSendBuffer, iSendLen);
if(iRet != EM_SUCCESS)
{
return iRet;
}
return recvBySep(sRecvBuffer, sSep);
}
int TC_TCPClient::sendRecvLine(const char* sSendBuffer, size_t iSendLen, string &sRecvBuffer)
{
return sendRecvBySep(sSendBuffer, iSendLen, sRecvBuffer, "\r\n");
}
int TC_TCPClient::sendRecvAll(const char* sSendBuffer, size_t iSendLen, string &sRecvBuffer)
{
int iRet = send(sSendBuffer, iSendLen);
if(iRet != EM_SUCCESS)
{
return iRet;
}
return recvAll(sRecvBuffer);
}
/*************************************TC_UDPClient**************************************/
int TC_UDPClient::checkSocket()
{
if(!_socket.isValid())
{
try
{
if(_port == 0)
{
_socket.createSocket(SOCK_DGRAM, AF_LOCAL);
}
else
{
_socket.createSocket(SOCK_DGRAM, AF_INET);
}
}
catch(TC_Socket_Exception &ex)
{
_socket.close();
return EM_SOCKET;
}
try
{
if(_port == 0)
{
_socket.connect(_ip.c_str());
if(_port == 0)
{
_socket.bind(_ip.c_str());
}
}
else
{
_socket.connect(_ip, _port);
}
}
catch(TC_SocketConnect_Exception &ex)
{
_socket.close();
return EM_CONNECT;
}
catch(TC_Socket_Exception &ex)
{
_socket.close();
return EM_SOCKET;
}
}
return EM_SUCCESS;
}
int TC_UDPClient::send(const char *sSendBuffer, size_t iSendLen)
{
int iRet = checkSocket();
if(iRet < 0)
{
return iRet;
}
iRet = _socket.send(sSendBuffer, iSendLen);
if(iRet <0 )
{
return EM_SEND;
}
return EM_SUCCESS;
}
int TC_UDPClient::recv(char *sRecvBuffer, size_t &iRecvLen)
{
string sTmpIp;
uint16_t iTmpPort;
return recv(sRecvBuffer, iRecvLen, sTmpIp, iTmpPort);
}
int TC_UDPClient::recv(char *sRecvBuffer, size_t &iRecvLen, string &sRemoteIp, uint16_t &iRemotePort)
{
int iRet = checkSocket();
if(iRet < 0)
{
return iRet;
}
TC_Epoller epoller(false);
epoller.create(1);
epoller.add(_socket.getfd(), 0, EPOLLIN);
int iRetCode = epoller.wait(_timeout);
if (iRetCode < 0)
{
return EM_SELECT;
}
else if (iRetCode == 0)
{
return EM_TIMEOUT;
}
epoll_event ev = epoller.get(0);
if(ev.events & EPOLLIN)
{
iRet = _socket.recvfrom(sRecvBuffer, iRecvLen, sRemoteIp, iRemotePort);
if(iRet <0 )
{
return EM_SEND;
}
iRecvLen = iRet;
return EM_SUCCESS;
}
return EM_SELECT;
}
int TC_UDPClient::sendRecv(const char *sSendBuffer, size_t iSendLen, char *sRecvBuffer, size_t &iRecvLen)
{
int iRet = send(sSendBuffer, iSendLen);
if(iRet != EM_SUCCESS)
{
return iRet;
}
return recv(sRecvBuffer, iRecvLen);
}
int TC_UDPClient::sendRecv(const char *sSendBuffer, size_t iSendLen, char *sRecvBuffer, size_t &iRecvLen, string &sRemoteIp, uint16_t &iRemotePort)
{
int iRet = send(sSendBuffer, iSendLen);
if(iRet != EM_SUCCESS)
{
return iRet;
}
return recv(sRecvBuffer, iRecvLen, sRemoteIp, iRemotePort);
}
}
边栏推荐
- Appium foundation - appium installation (II)
- Mysql 45讲学习笔记(十二)MySQL会“抖”一下
- Tree DP
- [untitled]
- SQL injection SQL lab 11~22
- Error CVC complex type 2.4. a: Invalid content beginning with element 'base extension' was found. Should start with one of '{layoutlib}'.
- tars源码分析之1
- Redis面试题集
- 金盾视频播放器拦截的软件关键词和进程信息
- 8. Factory method
猜你喜欢

Which water in the environment needs water quality monitoring

198. House raiding

Error CVC complex type 2.4. a: Invalid content beginning with element 'base extension' was found. Should start with one of '{layoutlib}'.

Webrtc quickly set up video call and video conference

Variables d'environnement personnalisées uniapp

P26-P34 third_ template

List of top ten professional skills required for data science work

746. Climb stairs with minimum cost

【问题记录】03 连接MySQL数据库提示:1040 Too many connections

Mysql 45讲学习笔记(七)行锁
随机推荐
[problem record] 03 connect to MySQL database prompt: 1040 too many connections
What is the "relative dilemma" in cognitive fallacy?
Detailed explanation of common APIs for component and container containers: frame, panel, scrollpane
Bicolor case
Stc8h development (XII): I2C drive AT24C08, at24c32 series EEPROM storage
《ClickHouse原理解析与应用实践》读书笔记(4)
Arcpy uses the updatelayer function to change the symbol system of the layer
Sort list tool class, which can sort strings
Mysql 45讲学习笔记(六)全局锁
MySQL installation and configuration
R statistical mapping - random forest classification analysis and species abundance difference test combination diagram
STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
After the festival, a large number of people change careers. Is it still time to be 30? Listen to the experience of the past people
STM32 单片机ADC 电压计算
SQL injection SQL lab 11~22
P26-P34 third_ template
雲原生——上雲必讀之SSH篇(常用於遠程登錄雲服務器)
Notes and notes
Mysql 45讲学习笔记(十三)表数据删掉一半,表文件大小不变
Displaying currency in Indian numbering format