RflySimSDK v4.01
RflySimSDK说明文档
载入中...
搜索中...
未找到
rfly_udp.h
1#pragma once
2
3#if defined(__linux__) || defined(__APPLE__)
4#include <netinet/in.h>
5#include <arpa/inet.h>
6#include <sys/socket.h>
7#include <sys/types.h>
8#include <sys/ioctl.h>
9#include <unistd.h>
10#include <netdb.h>
11#include <fcntl.h>
12#include <ifaddrs.h>
13#define nonblockingsocket(s) {unsigned long ctl = 1;}
14#elif _WIN32
15#include <winsock2.h>
16#include <ws2tcpip.h>
17#pragma comment(lib,"ws2_32.lib")
18#include <iphlpapi.h>
19#pragma comment(lib, "iphlpapi.lib")
20#define nonblockingsocket(s) {unsigned long ctl = 1;ioctlsocket( s, FIONBIO, &ctl );}
21#endif
22
23#include <string>
24#include <functional>
25#include <cerrno>
26#include <thread>
27#include <iostream>
28#include <algorithm>
29#include <cstring>
30#include <stdexcept>
31#include <vector>
32
33#define FDR_UNUSED(expr){ (void)(expr); }
34#define FDR_ON_ERROR std::function<void(int, std::string)> onError = [](int errorCode, std::string errorMessage){FDR_UNUSED(errorCode); FDR_UNUSED(errorMessage)}
35
36#ifndef BUFFER_SIZE_RFLY
37#define BUFFER_SIZE_RFLY 1024
38#endif
39
40// ===== 序列化工具 =====
41
42// 计算序列化后的大小
43template<typename T>
44size_t calculateSize(const T& obj);
45
46// 基本数据类型的大小计算
47template<typename T>
48inline size_t calculateSize(const T& value) {
49 static_assert(std::is_trivially_copyable<T>::value,
50 "Type must be trivially copyable for serialization");
51 return sizeof(T);
52}
53
54// std::string的大小计算
55inline size_t calculateSize(const std::string& str) {
56 return sizeof(uint32_t) + str.size();
57}
58
59// 普通数组的大小计算
60template<typename T, size_t N>
61inline size_t calculateSize(const T (&array)[N]) {
62 size_t total = 0;
63 for (size_t i = 0; i < N; ++i) {
64 total += calculateSize(array[i]);
65 }
66 return total;
67}
68
69// std::vector的大小计算
70template<typename T>
71inline size_t calculateSize(const std::vector<T>& vec) {
72 size_t total = sizeof(uint32_t); // 存储vector大小
73 for (const auto& element : vec) {
74 total += calculateSize(element);
75 }
76 return total;
77}
78
79// ===== 序列化到缓冲区 =====
80
81template<typename T>
82void serializeToBuffer(uint8_t* buffer, const T& value);
83
84// 基本数据类型的序列化
85template<typename T>
86inline void serializeToBuffer(uint8_t* buffer, const T& value) {
87 static_assert(std::is_trivially_copyable<T>::value,
88 "Type must be trivially copyable for serialization");
89 memcpy(buffer, &value, sizeof(value));
90}
91
92// std::string的序列化
93inline void serializeToBuffer(uint8_t* buffer, const std::string& str) {
94 uint32_t length = static_cast<uint32_t>(str.size());
95 memcpy(buffer, &length, sizeof(length));
96 buffer += sizeof(length);
97 memcpy(buffer, str.data(), length);
98}
99
100// 普通数组的序列化
101template<typename T, size_t N>
102inline void serializeToBuffer(uint8_t* buffer, const T (&array)[N]) {
103 for (size_t i = 0; i < N; ++i) {
104 serializeToBuffer(buffer, array[i]);
105 buffer += calculateSize(array[i]);
106 }
107}
108
109// std::vector的序列化
110template<typename T>
111inline void serializeToBuffer(uint8_t* buffer, const std::vector<T>& vec) {
112 uint32_t size = static_cast<uint32_t>(vec.size());
113 memcpy(buffer, &size, sizeof(size));
114 buffer += sizeof(size);
115
116 for (const auto& element : vec) {
117 serializeToBuffer(buffer, element);
118 buffer += calculateSize(element);
119 }
120}
121
122// ===== 从缓冲区反序列化 =====
123
124template<typename T>
125size_t deserializeFromBuffer(const uint8_t* buffer, T& value);
126
127// 基本数据类型的反序列化
128template<typename T>
129inline size_t deserializeFromBuffer(const uint8_t* buffer, T& value) {
130 static_assert(std::is_trivially_copyable<T>::value,
131 "Type must be trivially copyable for deserialization");
132 memcpy(&value, buffer, sizeof(value));
133 return sizeof(value);
134}
135
136// std::string的反序列化
137inline size_t deserializeFromBuffer(const uint8_t* buffer, std::string& str) {
138 uint32_t length;
139 memcpy(&length, buffer, sizeof(length));
140 buffer += sizeof(length);
141
142 str.assign(reinterpret_cast<const char*>(buffer), length);
143 return sizeof(length) + length;
144}
145
146// 普通数组的反序列化
147template<typename T, size_t N>
148inline size_t deserializeFromBuffer(const uint8_t* buffer, T (&array)[N]) {
149 size_t total = 0;
150 for (size_t i = 0; i < N; ++i) {
151 total += deserializeFromBuffer(buffer + total, array[i]);
152 }
153 return total;
154}
155
156// std::vector的反序列化
157template<typename T>
158inline size_t deserializeFromBuffer(const uint8_t* buffer, std::vector<T>& vec) {
159 uint32_t size;
160 memcpy(&size, buffer, sizeof(size));
161 buffer += sizeof(size);
162
163 vec.resize(size);
164 size_t total = sizeof(size);
165
166 for (size_t i = 0; i < size; ++i) {
167 total += deserializeFromBuffer(buffer + total - sizeof(size), vec[i]);
168 }
169 return total;
170}
171
172// ===== 打包/解包函数 =====
173
174// 打包函数 - 返回堆上分配的字节流和长度
175template<typename T>
176size_t packStruct(const T& obj, uint8_t* buffer) {
177 // 检查缓冲区是否有效
178 if (buffer == nullptr) {
179 throw std::invalid_argument("buffer cannot be null");
180 }
181 // 计算所需大小(用于返回,不分配内存)
182 size_t size = calculateSize(obj);
183 // 直接在传入的缓冲区中序列化
184 serializeToBuffer(buffer, obj);
185 // 返回实际序列化的大小(与计算的size一致)
186 return size;
187}
188
189// 解包函数 - 从字节流恢复结构体
190template<typename T>
191size_t unpackStruct(const uint8_t* buffer, T& obj) {
192 return deserializeFromBuffer(buffer, obj);
193}
194
195struct GenericInOut28 {
196 int32_t ioSilInts[8]; // 非静态成员:整数数组
197 float ioSilFloats[20]; // 非静态成员:浮点数数组
198
199 // 构造函数:初始化全部为0
200 GenericInOut28() {
201 memset(this, 0, sizeof(*this));
202 }
203};
204
205// 手动实现GenericInOut28的序列化/反序列化(不依赖宏)
206// 1. 计算大小
207inline size_t calculateSize(const GenericInOut28& obj) {
208 // 分别计算两个成员的大小并累加
209 return calculateSize(obj.ioSilInts) + calculateSize(obj.ioSilFloats);
210}
211
212// 2. 序列化到缓冲区
213inline void serializeToBuffer(uint8_t* buffer, const GenericInOut28& obj) {
214 // 先序列化整数数组,再移动指针
215 serializeToBuffer(buffer, obj.ioSilInts);
216 buffer += calculateSize(obj.ioSilInts); // 移动指针到整数数组末尾
217
218 // 再序列化浮点数数组
219 serializeToBuffer(buffer, obj.ioSilFloats);
220 // 指针无需再移动(后续操作由调用者处理)
221}
222
223// 3. 从缓冲区反序列化
224inline size_t deserializeFromBuffer(const uint8_t* buffer, GenericInOut28& obj) {
225 const uint8_t* start = buffer; // 记录起始位置
226
227 // 先反序列化整数数组,移动指针
228 buffer += deserializeFromBuffer(buffer, obj.ioSilInts);
229
230 // 再反序列化浮点数数组,移动指针
231 buffer += deserializeFromBuffer(buffer, obj.ioSilFloats);
232
233 // 返回总消耗的字节数
234 return buffer - start;
235}
236
237
238class BaseSocket
239{
240public:
241 enum SocketType
242 {
243 TCP = SOCK_STREAM,
244 UDP = SOCK_DGRAM
245 };
246 sockaddr_in address;
247 //char udpBuf[BUFFER_SIZE_RFLY+1];
248 //std::string RecvIP;
249 //uint16_t RecvPort;
250 std::string remoteAddress() const { return ipToString(this->address); }
251 int remotePort() const { return ntohs(this->address.sin_port); }
252 int fileDescriptor() const { return this->sock; }
253
254protected:
255 int sock = 0;
256
257 bool hasSetNoblock=false;
258
259
260
261 //bool isStopRec=false;
262
263 // Get std::string value of the IP from a `sockaddr_in` address struct
264 static std::string ipToString(const sockaddr_in& addr)
265 {
266 char ip[INET_ADDRSTRLEN];
267
268 struct sockaddr_in in;
269 memset(&in, 0, sizeof(in));
270 in.sin_family = AF_INET;
271 memcpy(&in.sin_addr, &(addr.sin_addr), sizeof(struct in_addr));
272 getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), ip, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
273
274 return std::string(ip);
275 }
276
277 static bool isVirtualMachineAdapter(const std::string& adapterName) {
278 std::vector<std::string> vmKeywords = {
279 "VMware", "VirtualBox", "Hyper-V", "QEMU"
280 };
281 for (const auto& keyword : vmKeywords) {
282 if (adapterName.find(keyword) != std::string::npos) {
283 return true;
284 }
285 }
286 return false;
287 }
288
289 // 函数用于获取静态 IP 地址,排除虚拟机网络
290 static std::vector<std::string> getStaticIPAddresses() {
291 std::vector<std::string> staticIPs;
292#ifdef _WIN32
293 ULONG outBufLen = 0;
294 // 首次调用以获取所需的缓冲区大小
295 if (GetAdaptersInfo(NULL, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
296 PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)malloc(outBufLen);
297 if (pAdapterInfo) {
298 // 再次调用以获取适配器信息
299 if (GetAdaptersInfo(pAdapterInfo, &outBufLen) == NO_ERROR) {
300 PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
301 while (pAdapter) {
302 std::string adapterName = pAdapter->Description;
303 // 检查是否为虚拟机网络
304 if (!isVirtualMachineAdapter(adapterName)) {
305 // 检查是否为静态分配的 IP
306 if (pAdapter->DhcpEnabled == FALSE) {
307 IP_ADDR_STRING* pIpAddr = &pAdapter->IpAddressList;
308 while (pIpAddr) {
309 staticIPs.emplace_back(pIpAddr->IpAddress.String);
310 pIpAddr = pIpAddr->Next;
311 }
312 }
313 }
314 pAdapter = pAdapter->Next;
315 }
316 }
317 free(pAdapterInfo);
318 }
319 }
320
321#endif
322 return staticIPs;
323 }
324
325 BaseSocket(FDR_ON_ERROR, SocketType sockType = TCP, int socketId = -1)
326 {
327 if (socketId == -1)
328 {
329 this->sock = (int)socket(AF_INET, sockType, 0);
330
331 if ( this->sock == -1 )
332 {
333 onError(errno, "Socket creating error.");
334 }
335 }
336 else
337 {
338 this->sock = socketId;
339 }
340 int rcvBufSize=102400*10;
341#ifndef __linux__
342 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, (char*)&rcvBufSize, sizeof(rcvBufSize));
343 rcvBufSize=102400*10;
344 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, (char*)&rcvBufSize, sizeof(rcvBufSize));
345#else
346 setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, &rcvBufSize, sizeof(rcvBufSize));
347 rcvBufSize=102400*10;
348 setsockopt(this->sock, SOL_SOCKET, SO_SNDBUF, &rcvBufSize, sizeof(rcvBufSize));
349#endif
350
351
352
353 }
354 virtual ~BaseSocket(){}
355};
356
357
358class UDPSocket : public BaseSocket
359{
360public:
361 std::function<void(std::string, std::string, uint16_t)> onMessageReceived;
362 std::function<void(const char*, size_t, std::string, uint16_t)> onRawMessageReceived;
363 bool isUseConnect = false;
364 //std::thread* mT;
365
366 void Close() {
367
368#ifndef __linux__
369 closesocket(this->sock);
370#else
371 shutdown(this->sock, SHUT_RDWR);
372 close(this->sock);
373#endif
374 }
375
376
377 explicit UDPSocket(bool useConnect = false, FDR_ON_ERROR, int socketId = -1): BaseSocket(onError, SocketType::UDP, socketId)
378 {
379 this->isUseConnect=useConnect;
380
381 }
382
383 void StartRecvThread()
384 {
385
386 if (this->isUseConnect)
387 {
388 std::thread t(Receive, this); // usage with Connect()
389 t.detach();
390 }
391 else
392 {
393 std::thread t(ReceiveFrom, this);
394 t.detach();
395 }
396
397 //this->isStopRec=false;
398 }
399
400 // Send raw bytes to a spesific `host` & `port` with no connection
401 int SendTo(const char* bytes, size_t byteslength, const char* host, uint16_t port, FDR_ON_ERROR)
402 {
403 sockaddr_in hostAddr;
404
405 //int status;
406 if((hostAddr.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
407 onError(errno, "SendTo: Invalid address. Address type not supported.");
408 }
409
410 // struct addrinfo hints, *res, *it;
411 // memset(&hints, 0, sizeof(hints));
412 // hints.ai_family = AF_INET;
413 // hints.ai_socktype = SOCK_DGRAM;
414
415 // int status;
416 // if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0)
417 // {
418 // onError(errno, "Invalid address." + std::string(gai_strerror(status)));
419 // return -1;
420 // }
421
422 // for (it = res; it != NULL; it = it->ai_next)
423 // {
424 // if (it->ai_family == AF_INET)
425 // { // IPv4
426 // memcpy((void* )(&hostAddr), (void* )it->ai_addr, sizeof(sockaddr_in));
427 // break; // for now, just get first ip (ipv4).
428 // }
429 // }
430
431 // freeaddrinfo(res);
432
433 hostAddr.sin_port = htons(port);
434 hostAddr.sin_family = AF_INET;
435
436 int sent_length = sendto(this->sock, bytes, (int)byteslength, 0, (sockaddr*)&hostAddr, sizeof(hostAddr));
437 if (sent_length == -1)
438 {
439 onError(errno, "Cannot send message to the address.");
440 return -1;
441 }
442
443 return sent_length;
444 }
445 // Send raw bytes to a spesific `host` & `port` with no connection
446 int SendTo(const char* bytes, size_t byteslength, const std::string& host, uint16_t port, FDR_ON_ERROR)
447 {
448 return this->SendTo(bytes, byteslength, host.c_str(), port, onError);
449 }
450 // Send std::string to a spesific `host` & `port` with no connection
451 int SendTo(const std::string& message, const char* host, uint16_t port, FDR_ON_ERROR)
452 {
453 return this->SendTo(message.c_str(), message.length(), host, port, onError);
454 }
455 // Send std::string to a spesific `host` & `port` with no connection
456 int SendTo(const std::string& message, const std::string& host, uint16_t port, FDR_ON_ERROR)
457 {
458 return this->SendTo(message.c_str(), message.length(), host.c_str(), port, onError);
459 }
460
461 // Send raw bytes to the `Connect()`ed server.
462 int Send(const char* bytes, size_t byteslength) { return send(this->sock, bytes, (int)byteslength, 0); }
463 // Send std::string to the `Connect()`ed server.
464 int Send(const std::string& message) { return this->Send(message.c_str(), message.length()); }
465
466 // Connect to a server with raw `uint32_t ipv4` and `uint16_t port` values.
467 void Connect(uint32_t ipv4, uint16_t port, FDR_ON_ERROR)
468 {
469 this->address.sin_family = AF_INET;
470 this->address.sin_port = htons(port);
471 this->address.sin_addr.s_addr = ipv4;
472
473 // Try to connect.
474 int status = connect(this->sock, (const sockaddr* )&this->address, sizeof(sockaddr_in));
475 if (status == -1)
476 {
477 onError(errno, "Connection failed to the host.");
478 return;
479 }
480 }
481 // Connect to a server with `host` address and `port` values.
482 void Connect(const char* host, uint16_t port, FDR_ON_ERROR)
483 {
484 // struct addrinfo hints, *res, *it;
485 // memset(&hints, 0, sizeof(hints));
486 // hints.ai_family = AF_INET;
487 // hints.ai_socktype = SOCK_DGRAM;
488
489 // int status = getaddrinfo(host, NULL, &hints, &res);
490 // if (status != 0)
491 // {
492 // onError(errno, "Invalid address." + std::string(gai_strerror(status)));
493 // return;
494 // }
495
496 // for (it = res; it != NULL; it = it->ai_next)
497 // {
498 // if (it->ai_family == AF_INET)
499 // { // IPv4
500 // memcpy((void* )(&this->address), (void*)it->ai_addr, sizeof(sockaddr_in));
501 // break; // for now, just get first ip (ipv4).
502 // }
503 // }
504
505 // freeaddrinfo(res);
506
507 if((this->address.sin_addr.s_addr =inet_addr(host))==INADDR_NONE){
508 onError(errno, "SendTo: Invalid address. Address type not supported.");
509 }
510 this->Connect((uint32_t)this->address.sin_addr.s_addr, port, onError);
511 }
512 // Connect to a server with `host` address and `port` values.
513 void Connect(const std::string& host, uint16_t port, FDR_ON_ERROR) { this->Connect(host.c_str(), port, onError); }
514
515private:
516 static void Receive(UDPSocket* udpSocket)
517 {
518 char tempBuffer[BUFFER_SIZE_RFLY+1];
519 size_t messageLength;
520 //std::cout<<"Receive thread.."<<std::endl;
521 while ((messageLength = recv(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0)) != -1)
522 {
523 //std::cout<<"Receive Msg.."<<std::endl;
524 tempBuffer[messageLength] = '\0';
525 if (udpSocket->onMessageReceived)
526 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
527
528 if (udpSocket->onRawMessageReceived)
529 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(udpSocket->address), ntohs(udpSocket->address.sin_port));
530 }
531 }
532
533 static void ReceiveFrom(UDPSocket* udpSocket)
534 {
535
536 sockaddr_in hostAddr;
537 socklen_t hostAddrSize = sizeof(hostAddr);
538
539 char tempBuffer[BUFFER_SIZE_RFLY+1];
540 size_t messageLength;
541 //std::cout<<"ReceiveFrom thread.."<<std::endl;
542 while ((messageLength = recvfrom(udpSocket->sock, tempBuffer, BUFFER_SIZE_RFLY, 0, (sockaddr* )&hostAddr, &hostAddrSize)) != -1)
543 {
544 //std::cout<<"Receive Msg.."<<std::endl;
545 tempBuffer[messageLength] = '\0';
546 if (udpSocket->onMessageReceived)
547 udpSocket->onMessageReceived(std::string(tempBuffer, messageLength), ipToString(hostAddr), ntohs(hostAddr.sin_port));
548
549 if (udpSocket->onRawMessageReceived)
550 udpSocket->onRawMessageReceived(tempBuffer, messageLength, ipToString(hostAddr), ntohs(hostAddr.sin_port));
551 //std::cout<<"ReceiveFrom thread.."<<tempBuffer<<messageLength<<std::endl;
552 }
553 }
554};
555
556
557class UDPServer : public UDPSocket
558{
559public:
560 // filter udp data according to ip
561 bool needFilter=false;
562 // Bind the custom address & port of the server.
563 void Bind(const char* addressin, uint16_t port, FDR_ON_ERROR)
564 {
565 // int status = inet_pton(AF_INET, addressin, &this->address.sin_addr);
566 // switch (status) {
567 // case -1:
568 // onError(errno, "Invalid address. Address type not supported.");
569 // return;
570 // case 0:
571 // onError(errno, "AF_INET is not supported. Please send message to developer.");
572 // return;
573 // default:
574 // break;
575 // }
576
577
578 if((this->address.sin_addr.s_addr =inet_addr(addressin))==INADDR_NONE){
579 onError(errno, "Invalid address. Address type not supported.");
580 }
581 //this->address.sin_addr =inet_addr(addressin);
582 this->address.sin_family = AF_INET;
583 this->address.sin_port = htons(port);
584
585
586 int status;
587 //set recv buffer and reuseIP
588#ifndef __linux__
589 bool bOpt = true;
590 status = setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOpt, sizeof(bOpt));
591 if (status == -1)
592 {
593 onError(errno, "Cannot set SO_REUSEADDR the socket.");
594 return;
595 }
596 // int rcvBufSize=602400;
597 // status = setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, (char*)&rcvBufSize, sizeof(rcvBufSize));
598 // {
599 // onError(errno, "Cannot set SO_RCVBUF the socket.");
600 // return;
601 // }
602
603#else
604 int flag0 = 1;
605 setsockopt(this->sock, SOL_SOCKET, SO_REUSEADDR, &flag0, sizeof(flag0) );
606 // int rcvBufSize=602400;
607 // setsockopt(this->sock, SOL_SOCKET, SO_RCVBUF, &rcvBufSize, sizeof(rcvBufSize));
608#endif
609
610 status = bind(this->sock, (const sockaddr*)&this->address, sizeof(this->address));
611 if (status == -1)
612 {
613 onError(errno, "Cannot bind the socket.");
614 return;
615 }
616
617 //this->StartRecvThread();
618 }
619
620 // Bind the address(0.0.0.0) & port of the server.
621 void Bind(uint16_t port, FDR_ON_ERROR)
622 {
623 //std::cout<<"Bind.."<<std::endl;
624 this->Bind("0.0.0.0", port, onError);
625 }
626
627 // For Sim, Bind 127.0.0.1 for Sim.
628 // For Real, if static ip "192.168.151.168" exist, bind it;
629 // else, bind a non "0.0.0.0" static ip;
630 // else, bind "0.0.0.0".
631 void BindAuto(bool isReal, uint16_t port, FDR_ON_ERROR)
632 {
633 std::cout<<"Bind Auto, with ip:\t";
634 if (isReal){
635 needFilter = true;
636 std::vector<std::string> staticIPs = getStaticIPAddresses();
637 std::string targetIP = "192.168.151.168";
638 auto it = std::find(staticIPs.begin(), staticIPs.end(), targetIP);
639 if (it != staticIPs.end()) {
640 this->Bind("192.168.151.168", port, onError);
641 std::cout<<targetIP<<std::endl;
642 } else {
643 std::string bindIP = "0.0.0.0";
644 for (const auto& ip : staticIPs) {
645 if (ip != "0.0.0.0") {
646 bindIP = ip;
647 break;
648 }
649 }
650 this->Bind(bindIP.c_str(), port, onError);
651 std::cout<<bindIP<<std::endl;
652 }
653 } else{
654 this->Bind("127.0.0.1", port, onError);
655 std::cout<<"127.0.0.1"<<std::endl;
656 }
657 }
658
659 // SET Multicast IP and add to group
660 void setMulticast(const char* GROUP_IP, FDR_ON_ERROR)
661 {
662
663 struct ip_mreq vmreq;
664
665 if((vmreq.imr_multiaddr.s_addr =inet_addr(GROUP_IP))==INADDR_NONE){
666 onError(errno, "setMulticast: Invalid address. Address type not supported.");
667 }
668 if((vmreq.imr_interface.s_addr =inet_addr("0.0.0.0"))==INADDR_NONE){
669 onError(errno, "setMulticast: Invalid address. Address type not supported.");
670 }
671
672 // inet_pton(AF_INET, GROUP_IP, &vmreq.imr_multiaddr);
673 // inet_pton(AF_INET, "0.0.0.0", &vmreq.imr_interface);
674
675#ifndef __linux__
676 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&vmreq, sizeof(vmreq));
677#else
678 int status = setsockopt(this->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &vmreq, sizeof(vmreq));
679#endif
680
681 if(status == -1)
682 {
683 onError(errno, "setsockopt(IP_ADD_MEMBERSHIP) failed.");
684 return;
685 }
686 }
687
688 // Enable or disable the SO_BROADCAST flag
689 void setBroadcast(bool value, FDR_ON_ERROR)
690 {
691 int broadcast = static_cast<int>(value);
692#ifndef __linux__
693 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof broadcast);
694#else
695 int status = setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast);
696#endif
697 if (status == -1)
698 {
699 onError(errno, "setsockopt(SO_BROADCAST) failed.");
700 return;
701 }
702 }
703
704 int RecvNoblock(char * buf, std::string &ip, int &port,int maxrecvlen=BUFFER_SIZE_RFLY)
705 {
706 if(!this->hasSetNoblock){
707 nonblockingsocket(this->sock);
708 this->hasSetNoblock=true;
709 }
710 int req_len=0;
711 int recvlen=0;
712 sockaddr_in hostAddr;
713 socklen_t hostAddrSize = sizeof(hostAddr);
714
715#ifndef __linux__
716 recvlen=recvfrom(this->sock, buf, maxrecvlen, 0, (struct sockaddr *)&hostAddr, &hostAddrSize);
717#else
718 recvlen=recvfrom(this->sock, buf, maxrecvlen, MSG_DONTWAIT, (struct sockaddr *)&hostAddr, (socklen_t *)(&hostAddrSize));
719#endif
720 if(recvlen>0){
721 ip=ipToString(hostAddr);
722 port = ntohs(hostAddr.sin_port);
723 buf[recvlen] = '\0';
724 }
725 return recvlen;
726 }
727
728
729};
定义 rfly_udp.h:558
定义 rfly_udp.h:195