关键词搜索

源码搜索 ×
×

tars源码分析之19

发布2022-07-10浏览677次

详情内容

这个文件太经典了,对网络编程socket感兴趣的你,千万不要错过:

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <netdb.h>
  4. #include <arpa/inet.h>
  5. #include <cerrno>
  6. #include <cassert>
  7. #include <ifaddrs.h>
  8. #include <sys/ioctl.h>
  9. #include <net/if.h>
  10. #include <net/if_arp.h>
  11. #include <netinet/tcp.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include "util/tc_socket.h"
  15. #include "util/tc_common.h"
  16. namespace tars
  17. {
  18. TC_Socket::TC_Socket() : _sock(INVALID_SOCKET), _bOwner(true), _iDomain(AF_INET)
  19. {
  20. }
  21. TC_Socket::~TC_Socket()
  22. {
  23. if(_bOwner)
  24. {
  25. close();
  26. }
  27. }
  28. void TC_Socket::init(int fd, bool bOwner, int iDomain)
  29. {
  30. if(_bOwner)
  31. {
  32. close();
  33. }
  34. _sock = fd;
  35. _bOwner = bOwner;
  36. _iDomain = iDomain;
  37. }
  38. void TC_Socket::createSocket(int iSocketType, int iDomain)
  39. {
  40. assert(iSocketType == SOCK_STREAM || iSocketType == SOCK_DGRAM);
  41. close();
  42. _iDomain = iDomain;
  43. _sock = socket(iDomain, iSocketType, 0);
  44. if(_sock < 0)
  45. {
  46. _sock = INVALID_SOCKET;
  47. throw TC_Socket_Exception("[TC_Socket::createSocket] create socket error! :" + string(strerror(errno)));
  48. }
  49. }
  50. void TC_Socket::getPeerName(string &sPeerAddress, uint16_t &iPeerPort)
  51. {
  52. assert(_iDomain == AF_INET);
  53. struct sockaddr stPeer;
  54. bzero(&stPeer, sizeof(struct sockaddr));
  55. socklen_t iPeerLen = sizeof(sockaddr);
  56. getPeerName(&stPeer, iPeerLen);
  57. char sAddr[INET_ADDRSTRLEN] = "\0";
  58. struct sockaddr_in *p = (struct sockaddr_in *)&stPeer;
  59. inet_ntop(_iDomain, &p->sin_addr, sAddr, sizeof(sAddr));
  60. sPeerAddress= sAddr;
  61. iPeerPort = ntohs(p->sin_port);
  62. }
  63. void TC_Socket::getPeerName(string &sPathName)
  64. {
  65. assert(_iDomain == AF_LOCAL);
  66. struct sockaddr_un stSock;
  67. bzero(&stSock, sizeof(struct sockaddr_un));
  68. socklen_t iSockLen = sizeof(stSock);
  69. getPeerName((struct sockaddr *)&stSock, iSockLen);
  70. sPathName = stSock.sun_path;
  71. }
  72. void TC_Socket::getPeerName(struct sockaddr *pstPeerAddr, socklen_t &iPeerLen)
  73. {
  74. if(getpeername(_sock, pstPeerAddr, &iPeerLen) < 0)
  75. {
  76. throw TC_Socket_Exception("[TC_Socket::getPeerName] getpeername error", errno);
  77. }
  78. }
  79. void TC_Socket::getSockName(string &sSockAddress, uint16_t &iSockPort)
  80. {
  81. assert(_iDomain == AF_INET);
  82. struct sockaddr stSock;
  83. bzero(&stSock, sizeof(struct sockaddr));
  84. socklen_t iSockLen = sizeof(sockaddr);
  85. getSockName(&stSock, iSockLen);
  86. char sAddr[INET_ADDRSTRLEN] = "\0";
  87. struct sockaddr_in *p = (struct sockaddr_in *)&stSock;
  88. inet_ntop(_iDomain, &p->sin_addr, sAddr, sizeof(sAddr));
  89. sSockAddress = sAddr;
  90. iSockPort = ntohs(p->sin_port);
  91. }
  92. void TC_Socket::getSockName(string &sPathName)
  93. {
  94. assert(_iDomain == AF_LOCAL);
  95. struct sockaddr_un stSock;
  96. bzero(&stSock, sizeof(struct sockaddr_un));
  97. socklen_t iSockLen = sizeof(stSock);
  98. getSockName((struct sockaddr *)&stSock, iSockLen);
  99. sPathName = stSock.sun_path;
  100. }
  101. void TC_Socket::getSockName(struct sockaddr *pstSockAddr, socklen_t &iSockLen)
  102. {
  103. if(getsockname(_sock, pstSockAddr, &iSockLen) < 0)
  104. {
  105. throw TC_Socket_Exception("[TC_Socket::getSockName] getsockname error", errno);
  106. }
  107. }
  108. int TC_Socket::accept(TC_Socket &tcSock, struct sockaddr *pstSockAddr, socklen_t &iSockLen)
  109. {
  110. assert(tcSock._sock == INVALID_SOCKET);
  111. int ifd;
  112. while ((ifd = ::accept(_sock, pstSockAddr, &iSockLen)) < 0 && errno == EINTR);
  113. tcSock._sock = ifd;
  114. tcSock._iDomain = _iDomain;
  115. return tcSock._sock;
  116. }
  117. void TC_Socket::parseAddr(const string &sAddr, struct in_addr &stSinAddr)
  118. {
  119. int iRet = inet_pton(AF_INET, sAddr.c_str(), &stSinAddr);
  120. if(iRet < 0)
  121. {
  122. throw TC_Socket_Exception("[TC_Socket::parseAddr] inet_pton error", errno);
  123. }
  124. else if(iRet == 0)
  125. {
  126. struct hostent stHostent;
  127. struct hostent *pstHostent;
  128. char buf[2048] = "\0";
  129. int iError;
  130. gethostbyname_r(sAddr.c_str(), &stHostent, buf, sizeof(buf), &pstHostent, &iError);
  131. if (pstHostent == NULL)
  132. {
  133. throw TC_Socket_Exception("[TC_Socket::parseAddr] gethostbyname_r error! :" + string(hstrerror(iError)));
  134. }
  135. else
  136. {
  137. stSinAddr = *(struct in_addr *) pstHostent->h_addr;
  138. }
  139. }
  140. }
  141. void TC_Socket::bind(const string &sServerAddr, int port)
  142. {
  143. assert(_iDomain == AF_INET);
  144. struct sockaddr_in bindAddr;
  145. bzero(&bindAddr, sizeof(bindAddr));
  146. bindAddr.sin_family = _iDomain;
  147. bindAddr.sin_port = htons(port);
  148. if (sServerAddr == "")
  149. {
  150. bindAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  151. }
  152. else
  153. {
  154. parseAddr(sServerAddr, bindAddr.sin_addr);
  155. }
  156. try
  157. {
  158. bind((struct sockaddr *)(&bindAddr), sizeof(bindAddr));
  159. }
  160. catch(...)
  161. {
  162. throw TC_Socket_Exception("[TC_Socket::bind] bind '" + sServerAddr + ":" + TC_Common::tostr(port) + "' error", errno);
  163. }
  164. }
  165. void TC_Socket::bind(const char *sPathName)
  166. {
  167. assert(_iDomain == AF_LOCAL);
  168. unlink(sPathName);
  169. struct sockaddr_un stBindAddr;
  170. bzero(&stBindAddr, sizeof(struct sockaddr_un));
  171. stBindAddr.sun_family = _iDomain;
  172. strncpy(stBindAddr.sun_path, sPathName, sizeof(stBindAddr.sun_path));
  173. try
  174. {
  175. bind((struct sockaddr *)&stBindAddr, sizeof(stBindAddr));
  176. }
  177. catch(...)
  178. {
  179. throw TC_Socket_Exception("[TC_Socket::bind] bind '" + string(sPathName) + "' error", errno);
  180. }
  181. }
  182. void TC_Socket::bind(struct sockaddr *pstBindAddr, socklen_t iAddrLen)
  183. {
  184. //如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间
  185. int iReuseAddr = 1;
  186. //设置
  187. setSockOpt(SO_REUSEADDR, (const void *)&iReuseAddr, sizeof(int), SOL_SOCKET);
  188. if(::bind(_sock, pstBindAddr, iAddrLen) < 0)
  189. {
  190. throw TC_Socket_Exception("[TC_Socket::bind] bind error", errno);
  191. }
  192. }
  193. void TC_Socket::close()
  194. {
  195. if (_sock != INVALID_SOCKET)
  196. {
  197. ::close(_sock);
  198. _sock = INVALID_SOCKET;
  199. }
  200. }
  201. int TC_Socket::connectNoThrow(const string &sServerAddr, uint16_t port)
  202. {
  203. assert(_iDomain == AF_INET);
  204. if (sServerAddr == "")
  205. {
  206. throw TC_Socket_Exception("[TC_Socket::connect] server address is empty error!");
  207. }
  208. struct sockaddr_in serverAddr;
  209. bzero(&serverAddr, sizeof(serverAddr));
  210. serverAddr.sin_family = _iDomain;
  211. parseAddr(sServerAddr, serverAddr.sin_addr);
  212. serverAddr.sin_port = htons(port);
  213. return connect((struct sockaddr *)(&serverAddr), sizeof(serverAddr));
  214. }
  215. int TC_Socket::connectNoThrow(struct sockaddr* addr)
  216. {
  217. assert(_iDomain == AF_INET);
  218. return connect(addr, sizeof(struct sockaddr));
  219. }
  220. void TC_Socket::connect(const string &sServerAddr, uint16_t port)
  221. {
  222. int ret = connectNoThrow(sServerAddr, port);
  223. if(ret < 0)
  224. {
  225. throw TC_SocketConnect_Exception("[TC_Socket::connect] connect error", errno);
  226. }
  227. }
  228. void TC_Socket::connect(const char *sPathName)
  229. {
  230. int ret = connectNoThrow(sPathName);
  231. if(ret < 0)
  232. {
  233. throw TC_SocketConnect_Exception("[TC_Socket::connect] connect error", errno);
  234. }
  235. }
  236. int TC_Socket::connectNoThrow(const char *sPathName)
  237. {
  238. assert(_iDomain == AF_LOCAL);
  239. struct sockaddr_un stServerAddr;
  240. bzero(&stServerAddr, sizeof(struct sockaddr_un));
  241. stServerAddr.sun_family = _iDomain;
  242. strncpy(stServerAddr.sun_path, sPathName, sizeof(stServerAddr.sun_path));
  243. return connect((struct sockaddr *)&stServerAddr, sizeof(stServerAddr));
  244. }
  245. int TC_Socket::connect(struct sockaddr *pstServerAddr, socklen_t serverLen)
  246. {
  247. return ::connect(_sock, pstServerAddr, serverLen);
  248. }
  249. void TC_Socket::listen(int iConnBackLog)
  250. {
  251. if (::listen(_sock, iConnBackLog) < 0)
  252. {
  253. throw TC_Socket_Exception("[TC_Socket::listen] listen error", errno);
  254. }
  255. }
  256. int TC_Socket::recv(void *pvBuf, size_t iLen, int iFlag)
  257. {
  258. return ::recv(_sock, pvBuf, iLen, iFlag);
  259. }
  260. int TC_Socket::send(const void *pvBuf, size_t iLen, int iFlag)
  261. {
  262. return ::send(_sock, pvBuf, iLen, iFlag);
  263. }
  264. int TC_Socket::recvfrom(void *pvBuf, size_t iLen, string &sFromAddr, uint16_t &iFromPort, int iFlags)
  265. {
  266. struct sockaddr stFromAddr;
  267. socklen_t iFromLen = sizeof(struct sockaddr);
  268. struct sockaddr_in *p = (struct sockaddr_in *)&stFromAddr;
  269. bzero(&stFromAddr, sizeof(struct sockaddr));
  270. int iBytes = recvfrom(pvBuf, iLen, &stFromAddr, iFromLen, iFlags);
  271. if (iBytes >= 0)
  272. {
  273. char sAddr[INET_ADDRSTRLEN] = "\0";
  274. inet_ntop(_iDomain, &p->sin_addr, sAddr, sizeof(sAddr));
  275. sFromAddr = sAddr;
  276. iFromPort = ntohs(p->sin_port);
  277. }
  278. return iBytes;
  279. }
  280. int TC_Socket::recvfrom(void *pvBuf, size_t iLen, struct sockaddr *pstFromAddr, socklen_t &iFromLen, int iFlags)
  281. {
  282. return ::recvfrom(_sock, pvBuf, iLen, iFlags, pstFromAddr, &iFromLen);
  283. }
  284. int TC_Socket::sendto(const void *pvBuf, size_t iLen, const string &sToAddr, uint16_t port, int iFlags)
  285. {
  286. struct sockaddr_in toAddr;
  287. bzero(&toAddr, sizeof(struct sockaddr_in));
  288. toAddr.sin_family = _iDomain;
  289. if (sToAddr == "")
  290. {
  291. toAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  292. }
  293. else
  294. {
  295. parseAddr(sToAddr, toAddr.sin_addr);
  296. }
  297. toAddr.sin_port = htons(port);
  298. return sendto(pvBuf, iLen, (struct sockaddr *)(&toAddr), sizeof(toAddr), iFlags);
  299. }
  300. int TC_Socket::sendto(const void *pvBuf, size_t iLen, struct sockaddr *pstToAddr, socklen_t iToLen, int iFlags)
  301. {
  302. return ::sendto(_sock, pvBuf, iLen, iFlags, pstToAddr, iToLen);
  303. }
  304. void TC_Socket::shutdown(int iHow)
  305. {
  306. if (::shutdown(_sock, iHow) < 0)
  307. {
  308. throw TC_Socket_Exception("[TC_Socket::shutdown] shutdown error", errno);
  309. }
  310. }
  311. void TC_Socket::setblock(bool bBlock)
  312. {
  313. assert(_sock != INVALID_SOCKET);
  314. setblock(_sock, bBlock);
  315. }
  316. int TC_Socket::setSockOpt(int opt, const void *pvOptVal, socklen_t optLen, int level)
  317. {
  318. return setsockopt(_sock, level, opt, pvOptVal, optLen);
  319. }
  320. int TC_Socket::getSockOpt(int opt, void *pvOptVal, socklen_t &optLen, int level)
  321. {
  322. return getsockopt(_sock, level, opt, pvOptVal, &optLen);
  323. }
  324. void TC_Socket::setNoCloseWait()
  325. {
  326. linger stLinger;
  327. stLinger.l_onoff = 1; //在close socket调用后, 但是还有数据没发送完毕的时候容许逗留
  328. stLinger.l_linger = 0; //容许逗留的时间为0秒
  329. if(setSockOpt(SO_LINGER, (const void *)&stLinger, sizeof(linger), SOL_SOCKET) == -1)
  330. {
  331. throw TC_Socket_Exception("[TC_Socket::setNoCloseWait] error", errno);
  332. }
  333. }
  334. void TC_Socket::setCloseWait(int delay)
  335. {
  336. linger stLinger;
  337. stLinger.l_onoff = 1; //在close socket调用后, 但是还有数据没发送完毕的时候容许逗留
  338. stLinger.l_linger = delay; //容许逗留的时间为delay秒
  339. if(setSockOpt(SO_LINGER, (const void *)&stLinger, sizeof(linger), SOL_SOCKET) == -1)
  340. {
  341. throw TC_Socket_Exception("[TC_Socket::setCloseWait] error", errno);
  342. }
  343. }
  344. void TC_Socket::setCloseWaitDefault()
  345. {
  346. linger stLinger;
  347. stLinger.l_onoff = 0;
  348. stLinger.l_linger = 0;
  349. if(setSockOpt(SO_LINGER, (const void *)&stLinger, sizeof(linger), SOL_SOCKET) == -1)
  350. {
  351. throw TC_Socket_Exception("[TC_Socket::setCloseWaitDefault] error", errno);
  352. }
  353. }
  354. void TC_Socket::setTcpNoDelay()
  355. {
  356. int flag = 1;
  357. if(setSockOpt(TCP_NODELAY, (char*)&flag, int(sizeof(int)), IPPROTO_TCP) == -1)
  358. {
  359. throw TC_Socket_Exception("[TC_Socket::setTcpNoDelay] error", errno);
  360. }
  361. }
  362. void TC_Socket::setKeepAlive()
  363. {
  364. int flag = 1;
  365. if(setSockOpt(SO_KEEPALIVE, (char*)&flag, int(sizeof(int)), SOL_SOCKET) == -1)
  366. {
  367. throw TC_Socket_Exception("[TC_Socket::setKeepAlive] error", errno);
  368. }
  369. }
  370. void TC_Socket::setSendBufferSize(int sz)
  371. {
  372. if(setSockOpt(SO_SNDBUF, (char*)&sz, int(sizeof(int)), SOL_SOCKET) == -1)
  373. {
  374. throw TC_Socket_Exception("[TC_Socket::setSendBufferSize] error", errno);
  375. }
  376. }
  377. int TC_Socket::getSendBufferSize()
  378. {
  379. int sz;
  380. socklen_t len = sizeof(sz);
  381. if(getSockOpt(SO_SNDBUF, (void*)&sz, len, SOL_SOCKET) == -1 || len != sizeof(sz))
  382. {
  383. throw TC_Socket_Exception("[TC_Socket::getSendBufferSize] error", errno);
  384. }
  385. return sz;
  386. }
  387. void TC_Socket::setRecvBufferSize(int sz)
  388. {
  389. if(setSockOpt(SO_RCVBUF, (char*)&sz, int(sizeof(int)), SOL_SOCKET) == -1)
  390. {
  391. throw TC_Socket_Exception("[TC_Socket::setRecvBufferSize] error", errno);
  392. }
  393. }
  394. int TC_Socket::getRecvBufferSize()
  395. {
  396. int sz;
  397. socklen_t len = sizeof(sz);
  398. if(getSockOpt(SO_RCVBUF, (void*)&sz, len, SOL_SOCKET) == -1 || len != sizeof(sz))
  399. {
  400. throw TC_Socket_Exception("[TC_Socket::getRecvBufferSize] error", errno);
  401. }
  402. return sz;
  403. }
  404. void TC_Socket::setblock(int fd, bool bBlock)
  405. {
  406. int val = 0;
  407. if ((val = fcntl(fd, F_GETFL, 0)) == -1)
  408. {
  409. throw TC_Socket_Exception("[TC_Socket::setblock] fcntl [F_GETFL] error", errno);
  410. }
  411. if(!bBlock)
  412. {
  413. val |= O_NONBLOCK;
  414. }
  415. else
  416. {
  417. val &= ~O_NONBLOCK;
  418. }
  419. if (fcntl(fd, F_SETFL, val) == -1)
  420. {
  421. throw TC_Socket_Exception("[TC_Socket::setblock] fcntl [F_SETFL] error", errno);
  422. }
  423. }
  424. void TC_Socket::createPipe(int fds[2], bool bBlock)
  425. {
  426. if(::pipe(fds) != 0)
  427. {
  428. throw TC_Socket_Exception("[TC_Socket::createPipe] error", errno);
  429. }
  430. try
  431. {
  432. setblock(fds[0], bBlock);
  433. setblock(fds[1], bBlock);
  434. }
  435. catch(...)
  436. {
  437. ::close(fds[0]);
  438. ::close(fds[1]);
  439. throw;
  440. }
  441. }
  442. vector<string> TC_Socket::getLocalHosts()
  443. {
  444. vector<string> result;
  445. TC_Socket ts;
  446. ts.createSocket(SOCK_STREAM, AF_INET);
  447. int cmd = SIOCGIFCONF;
  448. struct ifconf ifc;
  449. int numaddrs = 10;
  450. int old_ifc_len = 0;
  451. while(true)
  452. {
  453. int bufsize = numaddrs * static_cast<int>(sizeof(struct ifreq));
  454. ifc.ifc_len = bufsize;
  455. ifc.ifc_buf = (char*)malloc(bufsize);
  456. int rs = ioctl(ts.getfd(), cmd, &ifc);
  457. if(rs == -1)
  458. {
  459. free(ifc.ifc_buf);
  460. throw TC_Socket_Exception("[TC_Socket::getLocalHosts] ioctl error", errno);
  461. }
  462. else if(ifc.ifc_len == old_ifc_len)
  463. {
  464. break;
  465. }
  466. else
  467. {
  468. old_ifc_len = ifc.ifc_len;
  469. }
  470. numaddrs += 10;
  471. free(ifc.ifc_buf);
  472. }
  473. numaddrs = ifc.ifc_len / static_cast<int>(sizeof(struct ifreq));
  474. struct ifreq* ifr = ifc.ifc_req;
  475. for(int i = 0; i < numaddrs; ++i)
  476. {
  477. if(ifr[i].ifr_addr.sa_family == AF_INET)
  478. {
  479. struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(&ifr[i].ifr_addr);
  480. if(addr->sin_addr.s_addr != 0)
  481. {
  482. char sAddr[INET_ADDRSTRLEN] = "\0";
  483. inet_ntop(AF_INET, &(*addr).sin_addr, sAddr, sizeof(sAddr));
  484. result.push_back(sAddr);
  485. }
  486. }
  487. }
  488. free(ifc.ifc_buf);
  489. return result;
  490. }
  491. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载