当前位置:网站首页>tars源码分析之6
tars源码分析之6
2022-07-04 06:33:00 【涛歌依旧】
喜欢网络编程的同学,千万不要错过tars中关于socket的部分,来看看客户端操作。
真的是非常经典,看看send/recv吧,写得真是严密:
#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);
}
//设置非阻塞模式
_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;
}
}
}
}
//设置为阻塞模式
_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);
}
}
边栏推荐
- 云原生——上云必读之SSH篇(常用于远程登录云服务器)
- C # symmetric encryption (AES encryption) ciphertext results generated each time, different ideas, code sharing
- MySQL的information_schema数据库
- QT 获取随机颜色值设置label背景色 代码
- Invalid revision: 3.18.1-g262b901-dirty
- 70000 words of detailed explanation of the whole process of pad openvino [CPU] - from environment configuration to model deployment
- leetcode 310. Minimum Height Trees
- Common JS tool Libraries
- Tf/pytorch/cafe-cv/nlp/ audio - practical demonstration of full ecosystem CPU deployment - Intel openvino tool suite course summary (Part 2)
- 测试岗的中年危机该如何选择?是坚守还是另寻出路?且看下文
猜你喜欢
Appium基础 — APPium安装(二)
InputStream/OutputStream(文件的输入输出)
JSON Web Token----JWT和传统session登录认证对比
4G wireless all network solar hydrological equipment power monitoring system bms110
树形dp
[number theory] fast power (Euler power)
JS execution mechanism
ORICO ORICO outdoor power experience, lightweight and portable, the most convenient office charging station
Which water in the environment needs water quality monitoring
Cloud native - SSH article that must be read on the cloud (commonly used for remote login to ECS)
随机推荐
R statistical mapping - random forest classification analysis and species abundance difference test combination diagram
AWT common components, FileDialog file selection box
Matlab remainder
Abap:ooalv realizes the function of adding, deleting, modifying and checking
Explain in one sentence what social proof is
Realize IIC data / instruction interaction with micro batg135
STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
List of top ten professional skills required for data science work
颈椎、脚气
[Chongqing Guangdong education] electronic circuit homework question bank of RTVU secondary school
How to use multithreading to export excel under massive data? Source code attached!
QT qtablewidget table column top requirements ideas and codes
Functions in C language (detailed explanation)
2022.7.3-----leetcode.556
SQL join, left join, right join usage
采用中微BATG135实现IIC数据/指令交互
How to implement cross domain requests
Vant --- detailed explanation and use of list component in vant
STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
What is a spotlight effect?