network.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. /*
  2. * network.cpp
  3. *
  4. * Created on: 2022年3月4日
  5. * Author: pengzc
  6. */
  7. #include "network.h"
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. #include <poll.h>
  13. #include <sys/socket.h>
  14. #include <netdb.h>
  15. #include <arpa/inet.h>
  16. #include "utils/Log.h"
  17. namespace base {
  18. /**
  19. * 设置非阻塞模式
  20. */
  21. static int SetNonBlock(int fd) {
  22. int flags = fcntl(fd, F_GETFL, 0);
  23. if (flags < 0) {
  24. LOGE("Get flags error:%s", strerror(errno));
  25. return -1;
  26. }
  27. flags |= O_NONBLOCK;
  28. if (fcntl(fd, F_SETFL, flags) < 0) {
  29. LOGE("Set flags error:%s", strerror(errno));
  30. return -1;
  31. }
  32. return 0;
  33. }
  34. /**
  35. * -1 error
  36. * 0 timeout
  37. * >0 get event
  38. */
  39. static int Poll(int fd, int events, int timeout_millis, int* revents) {
  40. int ret = -1;
  41. struct pollfd pfd;
  42. memset(&pfd, 0, int(sizeof(pfd)));
  43. pfd.fd = fd;
  44. pfd.events = events;
  45. // retry again for EINTR
  46. for (int i = 0; i < 2; i++) {
  47. ret = ::poll(&pfd, 1, timeout_millis);
  48. if (-1 == ret && EINTR == errno)
  49. continue;
  50. break;
  51. }
  52. if (ret >= 0) {
  53. *revents = pfd.revents;
  54. }
  55. return ret;
  56. }
  57. static int NonBlockConnect(int fd, const struct sockaddr* ai_addr,
  58. socklen_t ai_addrlen, int timeout_millis) {
  59. /*设置套接字为非阻塞*/
  60. if (SetNonBlock(fd) != 0) {
  61. return SOCKET_ERROR;
  62. }
  63. /*阻塞情况下linux系统默认超时时间为75s*/
  64. int ret = ::connect(fd, ai_addr, ai_addrlen);
  65. if (ret == 0) {
  66. return ret;
  67. }
  68. if (errno != EINPROGRESS) {
  69. LOGE("connect failure, %s(%d)", strerror(errno), errno);
  70. return SOCKET_ERROR;
  71. }
  72. //LOGD("Doing connection.\n");
  73. /*正在处理连接*/
  74. int revents = 0;
  75. ret = Poll(fd, POLLIN | POLLOUT | POLLHUP | POLLERR | POLLNVAL,
  76. timeout_millis, &revents);
  77. if (ret < 0) {
  78. LOGE("poll failure, %s(%d)", strerror(errno), errno);
  79. return SOCKET_ERROR;
  80. }
  81. if (ret == 0) {
  82. return SOCKET_TIMEOUT;
  83. }
  84. if (((revents & POLLOUT) != 0) && ((revents & POLLIN) == 0)) {
  85. return SOCKET_SUCCESS;
  86. }
  87. if ((revents & POLLOUT) != 0 && (revents & POLLIN) != 0) {
  88. int err = 0;
  89. int errlen = sizeof(err);
  90. if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, (socklen_t*)&errlen)
  91. == -1) {
  92. LOGE("getsockopt failure, %s", strerror(errno));
  93. return SOCKET_ERROR;
  94. }
  95. if (err) {
  96. errno = err;
  97. LOGE("connect failure, %s(%d)", strerror(errno), errno);
  98. return SOCKET_ERROR;
  99. }
  100. }
  101. return SOCKET_ERROR;
  102. }
  103. static int Send(int sock_fd, const uint8_t* buffer, size_t buflen) {
  104. if (buflen <= 0) {
  105. return 0;
  106. }
  107. if (buffer == NULL) {
  108. return 0;
  109. }
  110. size_t tmp;
  111. size_t total = buflen;
  112. const unsigned char *p = buffer;
  113. while (true) {
  114. tmp = send(sock_fd, p, total, 0);
  115. if (tmp < 0) {
  116. // 当send收到信号时,可以继续写,但这里返回-1.
  117. if (errno == EINTR) {
  118. usleep(1000 * 100);
  119. continue;
  120. }
  121. // 当socket是非阻塞时,如返回此错误,表示写缓冲队列已满,
  122. // 在这里做延时后再重试.
  123. if (errno == EAGAIN) {
  124. usleep(1000 * 100);
  125. continue;
  126. }
  127. return -1;
  128. }
  129. if ((size_t) tmp == total) {
  130. // LOGD("send success");
  131. return buflen;
  132. }
  133. total -= tmp;
  134. p += tmp;
  135. }
  136. return tmp;
  137. }
  138. Socket::Socket() {
  139. socket_ = -1;
  140. }
  141. Socket::~Socket() {
  142. }
  143. int Socket::Connect(const std::string& host, int port, int timeout_millis) {
  144. if (socket_ >= 0) {
  145. LOGE("already connect");
  146. return SOCKET_ERROR;
  147. }
  148. struct addrinfo host_info;
  149. struct addrinfo * host_info_list = NULL;
  150. memset(&host_info, 0, int(sizeof(host_info)));
  151. host_info.ai_family = AF_UNSPEC;
  152. host_info.ai_socktype = SOCK_STREAM;
  153. char port_str[32] = {0};
  154. snprintf(port_str, int(sizeof(port_str)), "%d", port);
  155. int ret = getaddrinfo(host.c_str(), port_str, &host_info,
  156. &host_info_list);
  157. if (ret != 0) {
  158. LOGE("host could not be resolved");
  159. return SOCKET_GET_ADDRESS_INFO;
  160. }
  161. int sock = socket(host_info_list->ai_family, host_info_list->ai_socktype,
  162. host_info_list->ai_protocol);
  163. if (sock == -1) {
  164. LOGE("could not open socket, %s(%d)", strerror(errno), errno);
  165. freeaddrinfo(host_info_list);
  166. return SOCKET_INVALID;
  167. }
  168. ret = NonBlockConnect(sock, host_info_list->ai_addr,
  169. host_info_list->ai_addrlen, timeout_millis);
  170. if (ret != 0) {
  171. freeaddrinfo(host_info_list);
  172. close(sock);
  173. return ret;
  174. }
  175. socket_ = sock;
  176. freeaddrinfo(host_info_list);
  177. return 0;
  178. }
  179. int Socket::Write(uint8_t* data, int data_len) {
  180. if (socket_ < 0) {
  181. return SOCKET_INVALID;
  182. }
  183. return Send(socket_, data, data_len);
  184. }
  185. int Socket::Read(uint8_t* buffer, int buffer_len, int timeout_millis) {
  186. if (socket_ < 0) {
  187. //没有连接
  188. return SOCKET_INVALID;
  189. }
  190. int revents = 0;
  191. int ret = Poll(socket_, POLLIN | POLLHUP | POLLERR | POLLNVAL, timeout_millis, &revents);
  192. if (ret < 0) {
  193. return SOCKET_ERROR;
  194. }
  195. if (ret == 0) {
  196. return SOCKET_TIMEOUT;
  197. }
  198. int recv_bytes = recv(socket_, buffer, buffer_len, 0);
  199. if (recv_bytes == 0) {
  200. //连接已关闭
  201. //LOGD("recv 0, close it");
  202. Close();
  203. return 0;
  204. } else if (recv_bytes < 0) {
  205. //添加错误处理
  206. if ((errno == EINTR) || (errno == EWOULDBLOCK) || (errno == EAGAIN)) {
  207. //继续recv
  208. return SOCKET_TIMEOUT;
  209. } else {
  210. LOGE("recv: %s(%d)", strerror(errno), errno);
  211. Close();
  212. return SOCKET_ERROR;
  213. }
  214. }
  215. return recv_bytes;
  216. }
  217. int Socket::Close() {
  218. if (socket_ >= 0) {
  219. close(socket_);
  220. socket_ = -1;
  221. }
  222. return 0;
  223. }
  224. InetAddress Socket::inet_address() const {
  225. return address_;
  226. }
  227. //ServerSocket
  228. ServerSocket::ServerSocket(int port) {
  229. server_socket_ = socket(PF_INET, SOCK_STREAM, 0);
  230. if (server_socket_ < 0) {
  231. LOGE("socket failure, %s(%d)", strerror(errno), errno);
  232. return;
  233. }
  234. int on = 1;
  235. if (setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, &on,
  236. socklen_t(sizeof(on))) != 0) {
  237. LOGE("setsockopt failure, %s(%d)", strerror(errno), errno);
  238. goto failure;
  239. }
  240. memset(&server_addr_, 0, int(sizeof(server_addr_)));
  241. server_addr_.sin_family = AF_INET;
  242. server_addr_.sin_port = htons(port);
  243. server_addr_.sin_addr.s_addr = htonl(INADDR_ANY);
  244. if (bind(server_socket_, (struct sockaddr*) &server_addr_,
  245. socklen_t(sizeof(server_addr_))) < 0) {
  246. LOGE("bind failure, %s(%d)", strerror(errno), errno);
  247. goto failure;
  248. }
  249. if (listen(server_socket_, 64) < 0) {
  250. LOGE("listen failure, %s(%d)", strerror(errno), errno);
  251. goto failure;
  252. }
  253. return;
  254. failure:
  255. if (server_socket_ >= 0) {
  256. close(server_socket_);
  257. server_socket_ = -1;
  258. }
  259. }
  260. ServerSocket::~ServerSocket() {
  261. if (server_socket_ >= 0) {
  262. close(server_socket_);
  263. server_socket_ = -1;
  264. }
  265. }
  266. int ServerSocket::Accept(Socket* socket) {
  267. if (server_socket_ < 0) {
  268. return SOCKET_INVALID;
  269. }
  270. if (socket == NULL) {
  271. LOGE("argument socket must be not null");
  272. return SOCKET_INVALID;
  273. }
  274. socklen_t addr_len = socklen_t(sizeof(socket->address_.address_));
  275. int client = accept(server_socket_,
  276. (struct sockaddr*) &socket->address_.address_, &addr_len);
  277. if (client < 0) {
  278. LOGD("accept failure, %s(%d)", strerror(errno), errno);
  279. return SOCKET_ERROR;
  280. }
  281. socket->socket_ = client;
  282. return client;
  283. }
  284. InetAddress::InetAddress() {
  285. memset(&address_, 0, int(sizeof(address_)));
  286. }
  287. InetAddress::InetAddress(const std::string& host, int port) {
  288. memset(&address_, 0, int(sizeof(address_)));
  289. address_.sin_family = AF_INET;
  290. address_.sin_port = htons(port);
  291. address_.sin_addr.s_addr = inet_addr(host.c_str());
  292. }
  293. std::string InetAddress::ipv4() const {
  294. struct sockaddr_in in = {0};
  295. if (0 == memcmp(&address_, &in, int(sizeof(in)))) {
  296. //未初始化的地址返回空
  297. return "";
  298. }
  299. return inet_ntoa(address_.sin_addr);
  300. }
  301. DatagramSocket::DatagramSocket() {
  302. socket_ = socket(AF_INET, SOCK_DGRAM, 0);
  303. if (socket_ < 0) {
  304. LOGE("socket failure, %s(%d)", strerror(errno), errno);
  305. }
  306. }
  307. DatagramSocket::DatagramSocket(int port) {
  308. socket_ = socket(AF_INET, SOCK_DGRAM, 0);
  309. if (socket_ < 0) {
  310. LOGE("socket failure, %s(%d)", strerror(errno), errno);
  311. return;
  312. }
  313. struct sockaddr_in ser_addr;
  314. memset(&ser_addr, 0, int(sizeof(ser_addr)));
  315. ser_addr.sin_family = AF_INET;
  316. ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  317. ser_addr.sin_port = htons(port);
  318. int ret = bind(socket_, (struct sockaddr*) &ser_addr,
  319. socklen_t(sizeof(ser_addr)));
  320. if (ret < 0) {
  321. LOGE("bind failure, %s(%d)", strerror(errno), errno);
  322. close(socket_);
  323. socket_ = -1;
  324. }
  325. }
  326. DatagramSocket::~DatagramSocket() {
  327. }
  328. int DatagramSocket::SendTo(const InetAddress& address, const uint8_t* data,
  329. int len) {
  330. if (socket_ < 0) {
  331. return SOCKET_INVALID;
  332. }
  333. return sendto(socket_, data, len, 0, (sockaddr*) &address.address_,
  334. socklen_t(sizeof(address.address_)));
  335. }
  336. int DatagramSocket::Receive(InetAddress* address, uint8_t* buffer,
  337. int buffer_length, int timeout_millis) {
  338. if (socket_ < 0) {
  339. return SOCKET_INVALID;
  340. }
  341. int revents = 0;
  342. int ret = Poll(socket_, POLLIN, timeout_millis, &revents);
  343. if (ret < 0) {
  344. return SOCKET_ERROR;
  345. }
  346. if (ret == 0) {
  347. return SOCKET_TIMEOUT;
  348. }
  349. sockaddr* addr = NULL;
  350. socklen_t addr_len = 0;
  351. if (address != NULL) {
  352. addr = (sockaddr*) &address->address_;
  353. addr_len = sizeof(address->address_);
  354. }
  355. ret = recvfrom(socket_, buffer, buffer_length, 0, addr, &addr_len);
  356. if (ret == 0) {
  357. //连接已关闭
  358. Close();
  359. return 0;
  360. } else if (ret < 0) {
  361. if ((errno == EINTR) || (errno == EWOULDBLOCK) || (errno == EAGAIN)) {
  362. //继续recv
  363. return SOCKET_TIMEOUT;
  364. } else {
  365. LOGE("recv: %s(%d)", strerror(errno), errno);
  366. Close();
  367. return SOCKET_ERROR;
  368. }
  369. }
  370. return ret;
  371. }
  372. int DatagramSocket::Close() {
  373. if (socket_ >= 0) {
  374. close(socket_);
  375. socket_ = -1;
  376. }
  377. return 0;
  378. }
  379. #if 0 //测试程序段
  380. std::thread server_thread([](){
  381. net::ServerSocket server(8080);
  382. while(true) {
  383. net::Socket so;
  384. LOGE("服务端 等待连接");
  385. int ret = server.Accept(&so);
  386. if (ret < 0) {
  387. LOGE("Accept failure %d", ret);
  388. break;
  389. }
  390. const char* msg = "hello";
  391. uint8_t buf[1024] = {0};
  392. ret = so.Read(buf, int(sizeof(buf)), 2000);
  393. LOGE("服务端 读取 %d %s", ret, buf);
  394. ret = so.Write((uint8_t*)msg, strlen(msg));
  395. LOGE("服务端 发送 %d %s", ret, ret == strlen(msg) ? "成功" : "失败");
  396. so.Close();
  397. }
  398. });
  399. server_thread.detach();
  400. int test_count = 100000;
  401. usleep(1000 * 1000);
  402. while(test_count--) {
  403. LOGD("test count %d", test_count);
  404. net::Socket so;
  405. //net::Conn* conn = net::Dial("tcp", "14.215.177.38:80");
  406. // int ret = so.Connect("14.215.177.38", 80, 3000);
  407. int ret = so.Connect("127.0.0.1", 8080, 3000);
  408. // int ret = so.Connect("www.baidu.com", 80, 3000);
  409. LOGD("连接 %d", ret);
  410. if (ret == 0)
  411. {
  412. uint8_t buf[2048] = {0};
  413. const char* req = "GET / HTTP/1.1\r\nConnection: close\r\n\r\n";
  414. //发送
  415. ret = so.Write((uint8_t*)req, strlen(req));
  416. LOGD("客户端 写 %d", ret);
  417. while (true) {
  418. //读取,超时1000毫秒
  419. int n = so.Read(buf, int(sizeof(buf)) - 1, 1000);
  420. if (n > 0) {
  421. buf[n] = 0;
  422. LOGD("客户端 读取 %d字节: %s", n, buf);
  423. } else if (n == 0) {
  424. LOGD("客户端 连接正常断开");
  425. break;
  426. } else {
  427. if (n == net::SOCKET_TIMEOUT) {
  428. LOGD("客户端 读取超时, 继续读");
  429. continue;
  430. } else {
  431. LOGE("客户端 出错 %d", n);
  432. break;
  433. }
  434. }
  435. }
  436. //关闭连接
  437. so.Close();
  438. //释放内存
  439. }
  440. }
  441. #endif
  442. //测试UDP
  443. #if 0
  444. {
  445. std::thread server_thread([](){
  446. net::DatagramSocket server(8080);
  447. while(true) {
  448. LOGE("服务端 等待接收");
  449. net::InetAddress from_address;
  450. uint8_t buffer[1024] = {0};
  451. int ret = server.Receive(&from_address, buffer, int(sizeof(buffer)), 2000);
  452. if (ret == net::SOCKET_TIMEOUT) {
  453. LOGD("服务端接收超时");
  454. continue;
  455. }
  456. if (ret < 0) {
  457. LOGE("服务端接收出错 %d", ret);
  458. break;
  459. }
  460. LOGE("服务端 读取 来自 %s %d %s", from_address.ipv4().c_str(), ret, buffer);
  461. const char* msg = "hello";
  462. ret = server.SendTo(from_address, (uint8_t*)msg, int(strlen(msg)));
  463. LOGE("服务端 发送 %d %s", ret, ret == strlen(msg) ? "成功" : "失败");
  464. }
  465. });
  466. server_thread.detach();
  467. }
  468. usleep(1000 * 1000);
  469. {
  470. //UDP客户端
  471. net::InetAddress address("127.0.0.1", 8080);
  472. net::DatagramSocket so;
  473. while (true) {
  474. const char* msg = "I am from client";
  475. int ret = so.SendTo(address, (uint8_t*)msg, int(strlen(msg)));
  476. LOGE("客户端 发送 %d %s", ret, ret == strlen(msg) ? "成功" : "失败");
  477. uint8_t buffer[128] = {0};
  478. ret = so.Receive(&address, buffer, int(sizeof(buffer)), 2000);
  479. if (ret == net::SOCKET_TIMEOUT) {
  480. LOGE("客户端 接收超时");
  481. continue;
  482. }
  483. if (ret < 0) {
  484. LOGE("客户端 接收失败");
  485. break;
  486. }
  487. LOGE("客户端 接收 来自 %s %d %s", address.ipv4().c_str(), ret, buffer);
  488. }
  489. }
  490. #endif
  491. } /* namespace base */