当前位置:网站首页>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);
}
}
边栏推荐
- 微信小程序使用rich-text中图片宽度超出问题
- Arcpy 利用updatelayer函数改变图层的符号系统
- JS execution mechanism
- Which water in the environment needs water quality monitoring
- MySQL的information_schema数据库
- The solution of win11 taskbar right click without Task Manager - add win11 taskbar right click function
- JSON Web Token----JWT和传统session登录认证对比
- 树形dp
- buuctf-pwn write-ups (8)
- Appium foundation - appium installation (II)
猜你喜欢
《ClickHouse原理解析与应用实践》读书笔记(4)
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
How to choose the middle-aged crisis of the testing post? Stick to it or find another way out? See below
剑指 Offer II 038. 每日温度
Appium基础 — APPium安装(二)
2022 wechat enterprise mailbox login entry introduction, how to open and register enterprise wechat enterprise mailbox?
Review | categories and mechanisms of action of covid-19 neutralizing antibodies and small molecule drugs
List of top ten professional skills required for data science work
[backpack DP] backpack problem
Tree DP
随机推荐
[untitled]
2022 Xinjiang's latest eight members (Safety Officer) simulated examination questions and answers
High performance parallel programming and optimization | lesson 02 homework at home
FRP intranet penetration, reverse proxy
2022 wechat enterprise mailbox login entry introduction, how to open and register enterprise wechat enterprise mailbox?
740. Delete and get points
How to choose the middle-aged crisis of the testing post? Stick to it or find another way out? See below
Layoutmanager layout manager: flowlayout, borderlayout, GridLayout, gridbaglayout, CardLayout, BoxLayout
【无标题】
Distributed cap theory
Sword finger offer II 038 Daily temperature
Notes and notes
STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
Fundamentals of SQL database operation
Displaying currency in Indian numbering format
How to realize multi account login of video platform members
buuctf-pwn write-ups (8)
How to use multithreading to export excel under massive data? Source code attached!
Operator < <> > fool test case
MySQL installation and configuration