NSUKit 1.4.0
板卡级统一交互接口
载入中...
搜索中...
未找到
c_socket.cpp
浏览该文件的文档.
1#include "base/c_socket.h"
2
3using namespace nsukit;
4
5
6
7SocketGenerator::SocketGenerator(unsigned short int p, std::string c_ip, bool m) : port(p), ip(std::move(c_ip)),
8 mode(m) {
9 tcpClientConnected = false;
10}
11
12
14// std::cout << "free socket server" << std::endl;
16
17}
18
19
20void SocketGenerator::Init(bool update, unsigned short int port, std::string ip) {
21 if (update) {
22 port = port;
23 ip = ip;
24 }
25#ifdef _WIN32
26 // WinSock service initialization
27 WORD sockVersion = MAKEWORD(2, 2);
28 WSADATA wsaData;
29 if (WSAStartup(sockVersion, &wsaData) != 0) {
30 WSACleanup();
31 throw std::runtime_error("Winsock server Init failed");
32 }
33 addr_len = sizeof(SOCKADDR);
34 if (mode) {
35 tcpClient = socket(AF_INET, SOCK_STREAM, 0);
36 if (tcpClient == INVALID_SOCKET) {
37 throw std::runtime_error("socket client error");
38 }
39 addrCli.sin_family = AF_INET;
40 addrCli.sin_port = htons(port);
41 addrCli.sin_addr.S_un.S_addr = inet_addr(ip.c_str());
42
43 // Set 5s timeout
44 setsockopt(tcpClient, SOL_SOCKET, SO_RCVTIMEO, (char *)&recvTimeout, sizeof(recvTimeout));
45 } else {
46 tcpServer = socket(AF_INET, SOCK_STREAM, 0);
47 if (tcpServer == INVALID_SOCKET) {
48 throw "socket server error";
49 }
50 // Bind ip and port
51 addrSer.sin_family = AF_INET;
52 addrSer.sin_port = htons(port);
53 addrSer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
54 // addrSer.sin_addr.S_un.S_addr = inet_addr(ip);
55 if (bind(tcpServer, (SOCKADDR *) &addrSer, addr_len) == SOCKET_ERROR) {
56 throw "socket bind error";
57 }
58 if (listen(tcpServer, LISTEN_COUNT) == SOCKET_ERROR) {
59 throw "socket listen error";
60 }
61 }
62
63#else
64 addr_len = sizeof(struct sockaddr_in);
65 timeval timeout = {(int)(recvTimeout/1000), 0};
66 if (mode) {
67 tcpClient = socket(AF_INET, SOCK_STREAM, 0);
68 if (tcpClient == -1) {
69 throw "socket client error";
70 }
71 addrCli.sin_family = AF_INET;
72 addrCli.sin_port = htons(port);
73 addrCli.sin_addr.s_addr = inet_addr(ip.c_str());
74 // 设置5s超时
75 setsockopt(tcpClient, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
76 }
77 else {
78 tcpServer = socket(AF_INET, SOCK_STREAM, 0);
79 if (tcpServer == -1) {
80 throw "socket server error";
81 }
82 // 绑定ip和端口
83 addrSer.sin_family = AF_INET;
84 addrSer.sin_port = htons(port);
85 addrSer.sin_addr.s_addr = htonl(INADDR_ANY);
86 // addrSer.sin_addr.S_un.S_addr = inet_addr("192.168.1.111");
87 if (bind(tcpServer, (struct sockaddr*)&addrSer, addr_len) == -1) {
88 throw "socket bind error";
89 }
90 if (listen(tcpServer, LISTEN_COUNT) == -1) {
91 throw "socket listen error";
92 }
93 }
94
95#endif
96}
97
98
99int SocketGenerator::ConnectServer(float connect_time) {
100 // Returns -1 on failure, 0 on success
101 int ul, recv;
102#ifdef _WIN32
103 ul = 1;
104 ioctlsocket(tcpClient, FIONBIO, (unsigned long *) &ul);
105 recv = connect(tcpClient, (SOCKADDR *) &addrCli, addr_len); // Setting non-blocking returns -1,
106 ul = 0;
107 ioctlsocket(tcpClient, FIONBIO, (unsigned long *) &ul);
108#else
109 ul = fcntl(tcpClient, F_GETFL, 0);
110 fcntl(tcpClient, F_SETFL, ul | O_NONBLOCK);
111 recv = connect(tcpClient, (struct sockaddr*)&addrCli, addr_len);
112 ul = fcntl(tcpClient, F_GETFL, 0);
113 fcntl(tcpClient, F_SETFL, ul & ~O_NONBLOCK);
114#endif
115 tcpClientConnected = false;
116
117 fd_set rfds, wfds;
118 timeval tv = {(int)connect_time, 0};
119 FD_ZERO(&rfds);
120 FD_ZERO(&wfds);
121 FD_SET(tcpClient, &rfds);
122 FD_SET(tcpClient, &wfds);
123 /* set select() time out */
124// tv.tv_sec = connect_time; // s
125// tv.tv_usec = 0; // us
126 int selres = select(tcpClient + 1, &rfds, &wfds, NULL, &tv);
127 if (selres == 0) {
128 tv = {(int)connect_time, 0};
129 selres = select(tcpClient + 1, &rfds, &wfds, NULL, &tv);
130 }
131 switch (selres) {
132 case -1:
133 printf("select error\n");
134 break;
135 case 0:
136 printf("select time out\n");
137 break;
138 case 2:
139 printf("select time out\n");
140 break;
141 default:
142 if (FD_ISSET(tcpClient, &rfds) || FD_ISSET(tcpClient, &wfds)) {
143 // success
144 recv = 0;
145 tcpClientConnected = true;
146 }
147 break;
148 }
149
150 return recv;
151}
152
153
155 // Return -1 on failure
156#ifdef _WIN32
157 tcpClient = accept(tcpServer, (SOCKADDR *) &addrCli, &addr_len);
158 tcpClientConnected = true;
159 return tcpClient;
160#else
161 tcpClient = accept(tcpServer, (struct sockaddr*)&addrCli, &addr_len);
162 tcpClientConnected = true;
163 return tcpClient;
164#endif
165}
166
167// The sent data length is returned when send/recv is successful,
168// 0 is returned when the connection is completed,
169// and SOCKET_ERROR(-1) is returned when the connection fails.
170int SocketGenerator::RecvData(int s, char *buf, int len) {
171 int recv_count = recv(s, buf, len, 0);
172 if (recv_count > 0) {
173 return recv_count;
174 } else {
175 tcpClientConnected = false;
176 return 0;
177 }
178}
179
180
181int SocketGenerator::SendData(int s, char *buf, int len) {
182 int sent_count = send(s, buf, len, 0);
183 if (sent_count > 0) {
184 return sent_count;
185 } else {
186 tcpClientConnected = false;
187 return 0;
188 }
189}
190
191
193#ifdef _WIN32
194 closesocket(s);
195 WSACleanup();
196#else
197 close(s);
198#endif
199 tcpClientConnected = false;
200}
201
202
203int nsukit::TcpRecvBytes(SocketGenerator *s, char *buf, size_t len, bool *stopped) {
204 int rxLen = 0;
205 int totalLen = 0;
206 int cur_count;
207
208 while (len) {
209 if (stopped && *stopped) {
210 return 1;
211 }
212 cur_count = len - totalLen > BLOCK_SIZE ? BLOCK_SIZE : len - totalLen;
213 rxLen = s->RecvData(s->tcpClient, buf + totalLen, cur_count);
214 if (rxLen == 0) {
215 return 0;
216 } else if (rxLen > 0) {
217 totalLen += rxLen;
218 if (totalLen >= len) {
219 break;
220 }
221 }
222 }
223
224 return totalLen;
225}
226
227
228int nsukit::TcpSendBytes(SocketGenerator *s, char *buf, size_t len, bool *stopped) {
229 int stLen = 0;
230 int totalLen = 0;
231 int cur_count;
232
233 while (len) {
234 if (stopped && *stopped) {
235 return 1;
236 }
237 cur_count = len - totalLen > BLOCK_SIZE ? BLOCK_SIZE : len - totalLen;
238 stLen = s->SendData(s->tcpClient, buf + totalLen, cur_count);
239 if (stLen == 0) {
240 // server connect interrupt
241 return 0;
242 } else if (stLen > 0) {
243 totalLen += stLen;
244 if (totalLen >= len) {
245 break;
246 }
247 }
248 }
249
250 return 1;
251}
#define LISTEN_COUNT
Definition: c_socket.h:31
#define BLOCK_SIZE
Definition: c_socket.h:34
void Init(bool update, unsigned short int port=0, std::string ip="")
Definition: c_socket.cpp:20
int SendData(int s, char *buf, int len)
Definition: c_socket.cpp:181
int ConnectServer(float connect_time=SELECT_TIMEOUT)
Definition: c_socket.cpp:99
SocketGenerator(unsigned short int port=0, std::string ip="", bool mode=true)
Definition: c_socket.cpp:7
int RecvData(int s, char *buf, int len)
Definition: c_socket.cpp:170
int TcpRecvBytes(SocketGenerator *s, char *buf, size_t len, bool *stopped=nullptr)
Definition: c_socket.cpp:203
int TcpSendBytes(SocketGenerator *s, char *buf, size_t len, bool *stopped=nullptr)
Definition: c_socket.cpp:228
#define NULL
Definition: xdma_api.h:62