当前位置:网站首页>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);
}
}
边栏推荐
- C language - Blue Bridge Cup - Snake filling
- 《国民经济行业分类GB/T 4754—2017》官网下载地址
- Overview of convolutional neural network structure optimization
- MySQL information_ Schema database
- What is tweeman's law?
- How to choose the middle-aged crisis of the testing post? Stick to it or find another way out? See below
- Mysql 45讲学习笔记(十一)字符串字段怎么加索引
- 17-18. Dependency scope and life cycle plug-ins
- C language exercises (recursion)
- MySQL learning notes 3 - JDBC
猜你喜欢
P26-P34 third_ template
Reading notes of Clickhouse principle analysis and Application Practice (4)
C實現貪吃蛇小遊戲
【问题记录】03 连接MySQL数据库提示:1040 Too many connections
[MySQL] introduction, function, creation, view, deletion and modification of database view (with exercises)
uniapp 自定義環境變量
Webrtc quickly set up video call and video conference
Error CVC complex type 2.4. a: Invalid content beginning with element 'base extension' was found. Should start with one of '{layoutlib}'.
How to use multithreading to export excel under massive data? Source code attached!
《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
[problem record] 03 connect to MySQL database prompt: 1040 too many connections
QT get random color value and set label background color code
Explain in one sentence what social proof is
Sleep quality today 78 points
GoogleChromePortable 谷歌chrome浏览器便携版官网下载方式
Invalid bound statement (not found): com. example. mapper. TblUserRecordMapper. login
tars源码分析之2
Functions in C language (detailed explanation)
Variables d'environnement personnalisées uniapp
tars源码分析之5
Bicolor case
Sort list tool class, which can sort strings
C實現貪吃蛇小遊戲
Overview of convolutional neural network structure optimization
InputStream/OutputStream(文件的输入输出)
tars源码分析之4
SQL join, left join, right join usage
tars源码分析之10
实用的小工具指令