network.cc
Go to the documentation of this file.
1 /* Copyright 2017 UFACTORY Inc. All Rights Reserved.
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Author: Jimy Zhang <jimy92@163.com>
6  ============================================================================*/
7  // #define _WINSOCK_DEPRECATED_NO_WARNINGS
8 
9 #include <stdio.h>
10 #include <string.h>
11 #include <iostream>
12 
13 #ifdef _WIN32
14 #include <winsock2.h>
15 #pragma comment(lib, "ws2_32.lib")
16 #include <cstring>
17 #include<ws2tcpip.h>
18 #include<MSTCPiP.h>
19 #else
20 #include <errno.h>
21 #include <unistd.h>
22 #include <arpa/inet.h>
23 #include <net/if.h>
24 #include <netinet/tcp.h>
25 #include <sys/ioctl.h>
26 #endif
27 
28 #ifdef _WIN32
29 #ifndef inet_pton
30 extern "C" {
31  WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf);
32 }
33 #endif
34 #endif
35 
36 #include "xarm/core/os/network.h"
37 
38 #define DB_FLG "[net work] "
39 #define PRINT_ERR printf
40 
41 #ifdef _WIN32
42 #define PERRNO(ret, db_flg, str) \
43  { \
44  if (-1 == ret) { \
45  PRINT_ERR("%s%s, errno=%d\n", db_flg, str, WSAGetLastError()); \
46  return -1; \
47  } \
48  \
49 }
50 #else
51 #define PERRNO(ret, db_flg, str) \
52  { \
53  if (-1 == ret) { \
54  PRINT_ERR("%s%s, errno=%d\n", db_flg, str, errno); \
55  return -1; \
56  } \
57  \
58 }
59 #endif
60 
61 #ifdef _WIN32
62 
63 int socket_init(char *local_ip, int port, int is_server) {
64  // int iResult;
65  // WSADATA wsaData;
66  // iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
67  // if (iResult != 0) {
68  // printf("WSAStartup failed: %d\n", iResult);
69  // return -1;
70  // }
71  // struct addrinfo *result = NULL, *ptr = NULL, hints;
72  // ZeroMemory(&hints, sizeof(hints));
73  // hints.ai_family = AF_INET; // AF_UNSPEC;
74  // hints.ai_socktype = SOCK_STREAM;
75  // hints.ai_protocol = IPPROTO_TCP;
76  // if (is_server) hints.ai_flags = AI_PASSIVE;
77  // iResult = getaddrinfo(local_ip, port, &hints, &result);
78  // if (iResult != 0) {
79  // printf("getaddrinfo failed: %d\n", iResult);
80  // WSACleanup();
81  // return -1;
82  // }
83  // SOCKET sockfd = INVALID_SOCKET;
84  // // Attempt to connect to the first address returned by
85  // // the call to getaddrinfo
86  // ptr = result;
87 
88  // // Create a SOCKET for connecting to server
89  // sockfd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
90  // if (sockfd == INVALID_SOCKET) {
91  // printf("Error at socket(): %ld\n", WSAGetLastError());
92  // freeaddrinfo(result);
93  // WSACleanup();
94  // return -1;
95  // }
96  // if (is_server) {
97  // iResult = bind(sockfd, result->ai_addr, (int)result->ai_addrlen);
98  // if (iResult == SOCKET_ERROR) {
99  // printf("bind failed with error: %d\n", WSAGetLastError());
100  // freeaddrinfo(result);
101  // closesocket(sockfd);
102  // WSACleanup();
103  // return -1;
104  // }
105  // }
106 
107  WORD sockVersion = MAKEWORD(2, 2);
108  WSADATA data;
109  PERRNO(WSAStartup(sockVersion, &data), DB_FLG, "Error: ESAStartup");
110  int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
111  PERRNO(sockfd, DB_FLG, "Error: socket");
112 
113  int on = 1;
114  int keepAlive = 1; // Turn on keepalive attribute
115  int keepIdle = 1; // If there is no data in n seconds, probe
116  int keepInterval = 1; // Detection interval,5 seconds
117  int keepCount = 3; // 3 detection attempts
118  struct timeval timeout = { 2, 0 };
119 
120  int ret =
121  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
122  PERRNO(ret, DB_FLG, "Error: setsockopt[SO_REUSEADDR]");
123  ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepAlive,
124  sizeof(keepAlive));
125  PERRNO(ret, DB_FLG, "Error: setsockopt[SO_KEEPALIVE]");
126 
127  tcp_keepalive alive_in;
128  tcp_keepalive alive_out;
129  alive_in.keepalivetime = 2000; // 1s TCP_KEEPIDLE
130  alive_in.keepaliveinterval = 5000; //1s TCP_KEEPINTVL
131  alive_in.onoff = 1;
132  unsigned long ulBytesReturn = 0;
133  ret = WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, &alive_in, sizeof(alive_in),
134  &alive_out, sizeof(alive_out), &ulBytesReturn, NULL, NULL);
135  if (ret == SOCKET_ERROR)
136  {
137  PERRNO(ret, DB_FLG, "Error: WSAIoctl failed");
138  }
139  /*
140  ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&keepIdle,
141  sizeof(keepIdle));
142  PERRNO(ret, DB_FLG, "error: setsockopt");
143  ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&keepInterval,
144  sizeof(keepInterval));
145  PERRNO(ret, DB_FLG, "error: setsockopt");
146  ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, (char *)&keepCount,
147  sizeof(keepCount));
148  PERRNO(ret, DB_FLG, "error: setsockopt");
149  */
150  ret = setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
151  sizeof(struct timeval));
152  PERRNO(ret, DB_FLG, "Error: setsockopt[SO_SNDTIMEO]");
153 
154  if (is_server) {
155  struct sockaddr_in local_addr;
156  local_addr.sin_family = AF_INET;
157  local_addr.sin_port = htons(port);
158  // local_addr.sin_addr.s_addr = inet_addr(local_ip);
159  inet_pton(AF_INET, local_ip, (void *)&local_addr.sin_addr.S_un.S_addr);
160  ret = bind(sockfd, (struct sockaddr *)&local_addr, sizeof(local_addr));
161  PERRNO(ret, DB_FLG, "Error: bind");
162 
163  int ret = listen(sockfd, 10);
164  PERRNO(ret, DB_FLG, "Error: listen");
165  }
166  return sockfd;
167 }
168 
169 int socket_connect_server(int *socket, char server_ip[], int server_port) {
170  struct sockaddr_in server_addr;
171  server_addr.sin_family = AF_INET;
172  server_addr.sin_port = htons(server_port);
173  //inet_aton(server_ip, &server_addr.sin_addr);
174  inet_pton(AF_INET, server_ip, &server_addr.sin_addr);
175  //InetPton(AF_INET, server_ip, &server_addr.sin_addr);
176  int ret =
177  connect(*socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
178  PERRNO(ret, DB_FLG, "Error: connect");
179  return 0;
180 }
181 
182 int socket_send_data(int client_fp, unsigned char *data, int len) {
183  int ret = send(client_fp, (char *)data, len, 0);
184  PERRNO(ret, DB_FLG, "Error: socket_send_data");
185  return ret;
186 }
187 
188 #else
189 
190 int socket_init(char *local_ip, int port, int is_server) {
191  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
192  PERRNO(sockfd, DB_FLG, "Error: socket");
193 
194  int on = 1;
195  int keepAlive = 1; // Turn on keepalive attribute
196  int keepIdle = 60; // If there is no data in n seconds, probe
197  int keepInterval = 10; // Detection interval,5 seconds
198  int keepCount = 3; // 3 detection attempts
199  struct timeval timeout = { 2, 0 };
200 
201  int ret =
202  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
203  PERRNO(ret, DB_FLG, "Error: setsockopt[SO_REUSEADDR]");
204  ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive,
205  sizeof(keepAlive));
206  PERRNO(ret, DB_FLG, "Error: setsockopt[SO_KEEPALIVE]");
207  ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle,
208  sizeof(keepIdle));
209  PERRNO(ret, DB_FLG, "Error: setsockopt[TCP_KEEPIDLE]");
210  ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval,
211  sizeof(keepInterval));
212  PERRNO(ret, DB_FLG, "Error: setsockopt[TCP_KEEPINTVL]");
213  ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount,
214  sizeof(keepCount));
215  PERRNO(ret, DB_FLG, "Error: setsockopt[TCP_KEEPCNT]");
216  ret = setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
217  sizeof(struct timeval));
218  PERRNO(ret, DB_FLG, "Error: setsockopt[SO_SNDTIMEO]");
219 
220  if (is_server) {
221  struct sockaddr_in local_addr;
222  local_addr.sin_family = AF_INET;
223  local_addr.sin_port = htons(port);
224  local_addr.sin_addr.s_addr = inet_addr(local_ip);
225  ret = bind(sockfd, (struct sockaddr *)&local_addr, sizeof(local_addr));
226  PERRNO(ret, DB_FLG, "Error: bind");
227 
228  int ret = listen(sockfd, 10);
229  PERRNO(ret, DB_FLG, "Error: listen");
230  }
231  return sockfd;
232 }
233 
234 int socket_connect_server(int *socket, char server_ip[], int server_port) {
235  struct sockaddr_in server_addr;
236  server_addr.sin_family = AF_INET;
237  server_addr.sin_port = htons(server_port);
238  inet_aton(server_ip, &server_addr.sin_addr);
239  int ret =
240  connect(*socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
241  PERRNO(ret, DB_FLG, "Error: connect");
242  return 0;
243 }
244 
245 int socket_send_data(int client_fp, unsigned char *data, int len) {
246  int ret = send(client_fp, (void *)data, len, 0);
247  PERRNO(ret, DB_FLG, "Error: socket_send_data");
248  return ret;
249 }
250 
251 #endif
int socket_connect_server(int *socket, char server_ip[], int server_port)
Definition: network.cc:234
int socket_send_data(int client_fp, unsigned char *data, int len)
Definition: network.cc:245
int socket_init(char *local_ip, int port, int is_server)
Definition: network.cc:190
#define PERRNO(ret, db_flg, str)
Definition: network.cc:51
#define DB_FLG
Definition: network.cc:38


xarm_api
Author(s):
autogenerated on Sat May 8 2021 02:51:23