当前位置:网站首页>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);
}
}
边栏推荐
- Can the out of sequence message complete TCP three handshakes
- 2022.7.3-----leetcode. five hundred and fifty-six
- 2022.7.3-----leetcode.556
- QT 获取随机颜色值设置label背景色 代码
- Tree DP
- 运算符<< >>傻瓜式测试用例
- 测试岗的中年危机该如何选择?是坚守还是另寻出路?且看下文
- 70000 words of detailed explanation of the whole process of pad openvino [CPU] - from environment configuration to model deployment
- QT get random color value and set label background color code
- 【无标题】
猜你喜欢

QT qtablewidget table column top requirements ideas and codes

Appium基础 — APPium安装(二)

Download kicad on Alibaba cloud image station

Layoutmanager layout manager: flowlayout, borderlayout, GridLayout, gridbaglayout, CardLayout, BoxLayout

Common usage of time library

Abap:ooalv realizes the function of adding, deleting, modifying and checking

uniapp 自定义环境变量

ORICO ORICO outdoor power experience, lightweight and portable, the most convenient office charging station

Distributed cap theory
![[number theory] fast power (Euler power)](/img/1e/5d032c8f2e43f553b4543d28ea2a2d.jpg)
[number theory] fast power (Euler power)
随机推荐
Reading notes of Clickhouse principle analysis and Application Practice (4)
Fundamentals of SQL database operation
Explain in one sentence what social proof is
Understanding of cross domain and how to solve cross domain problems
手动对list进行分页(参数list ,当前页,页面大小)
C實現貪吃蛇小遊戲
JSON web token -- comparison between JWT and traditional session login authentication
SQL injection SQL lab 11~22
The width of the picture in rich text used by wechat applet exceeds the problem
Bicolor case
Matlab remainder
How to realize multi account login of video platform members
How does apscheduler set tasks not to be concurrent (that is, execute the next task after the first one)?
2022.7.3-----leetcode.556
Another company raised the price of SAIC Roewe new energy products from March 1
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
ABCD four sequential execution methods, extended application
8. Factory method
Review | categories and mechanisms of action of covid-19 neutralizing antibodies and small molecule drugs
17-18. Dependency scope and life cycle plug-ins