YDLIDAR SDK  V1.3.6
SimpleSocket.h
1 /*---------------------------------------------------------------------------*/
2 /* */
3 /* SimpleSocket.h - Simple Socket base class decleration. */
4 /* */
5 /* Author : Mark Carrier (mark@carrierlabs.com) */
6 /* */
7 /*---------------------------------------------------------------------------*/
8 /* Copyright (c) 2007-2009 CarrierLabs, LLC. All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  *
17  * 2. Redistributions in binary form must reproduce the above copyright
18  * notice, this list of conditions and the following disclaimer in
19  * the documentation and/or other materials provided with the
20  * distribution.
21  *
22  * 3. The name of the author may not be used to endorse or promote products
23  * derived from this software without specific prior written permission.
24  *
25  * 4. The name "CarrierLabs" must not be used to
26  * endorse or promote products derived from this software without
27  * prior written permission. For written permission, please contact
28  * mark@carrierlabs.com.
29  *
30  * THIS SOFTWARE IS PROVIDED BY MARK CARRIER ``AS IS'' AND ANY
31  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MARK CARRIER OR
34  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41  * OF THE POSSIBILITY OF SUCH DAMAGE.
42  *----------------------------------------------------------------------------*/
43 #ifndef __SOCKET_H__
44 #define __SOCKET_H__
45 
46 #include <sys/stat.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <stdarg.h>
50 #include <errno.h>
51 #include <assert.h>
52 #include <thread>
53 #include <chrono>
54 
55 
56 #if defined(__linux__) || defined (_DARWIN)
57 #include <sys/socket.h>
58 #include <netinet/in.h>
59 #include <arpa/inet.h>
60 #include <netinet/tcp.h>
61 #include <netinet/ip.h>
62 #include <netdb.h>
63 #endif
64 #ifdef __linux__
65 #include <linux/if_packet.h>
66 #include <linux/if_ether.h>
67 #include <linux/if.h>
68 #include <sys/sendfile.h>
69 #endif
70 #ifdef _DARWIN
71 #include <net/if.h>
72 #endif
73 #if defined(__linux__) || defined (_DARWIN)
74 #include <sys/time.h>
75 #include <sys/uio.h>
76 #include <unistd.h>
77 #include <fcntl.h>
78 #include <sys/ioctl.h>
79 #endif
80 
81 #if defined(_WIN32)
82 #include <io.h>
83 #include <winsock2.h>
84 #include <Ws2tcpip.h>
85 
86 # pragma warning(disable: 4786)
87 # pragma comment(lib, "ws2_32.lib")
88 
89 #define IPTOS_LOWDELAY 0x10
90 
91 #endif
92 #include "Host.h"
93 #include "StatTimer.h"
94 #include "ChannelDevice.h"
95 
96 //-----------------------------------------------------------------------------
97 // General class macro definitions and typedefs
98 //-----------------------------------------------------------------------------
99 #ifndef INVALID_SOCKET
100 #define INVALID_SOCKET ~(0)
101 #endif
102 
103 #define SOCKET_SENDFILE_BLOCKSIZE 8192
104 
105 namespace ydlidar {
106 
107 
115 public:
117  typedef enum
118  {
119  Receives = SHUT_RD,
120  Sends = SHUT_WR,
121  Both = SHUT_RDWR
122  } CShutdownMode;
123 
125  typedef enum
126  {
133  } CSocketType;
134 
136  typedef enum
137  {
138  SocketError = -1,
157  } CSocketError;
158 
159 public:
160  explicit CSimpleSocket(CSocketType type = SocketTypeTcp);
161  explicit CSimpleSocket(CSimpleSocket &socket);
162 
163  virtual ~CSimpleSocket()
164  {
165  if (m_pBuffer != NULL)
166  {
167  delete [] m_pBuffer;
168  m_pBuffer = NULL;
169  }
170  };
171 
176  virtual bool Initialize(void);
177 
180  virtual bool Close(void);
181 
188  virtual bool Shutdown(CShutdownMode nShutdown);
189 
196  virtual bool Select(void) {
197  return Select(0,0);
198  };
199 
207  virtual bool Select(int32_t nTimeoutSec, int32_t nTimeoutUSec);
208 
209 
210  virtual int WaitForData(size_t data_count, uint32_t timeout, size_t * returned_size);
211 
215  virtual bool IsSocketValid(void) {
216  return (m_socket != SocketError);
217  };
218 
222  void TranslateSocketError(void);
223 
226  static const char *DescribeError(CSocketError err);
227  inline const char *DescribeError() {
228  return DescribeError(m_socketErrno);
229  };
230 
239  virtual int32_t Receive(int32_t nMaxBytes = 1, uint8_t * pBuffer = 0);
240 
247  virtual int32_t Send(const uint8_t *pBuf, size_t bytesToSend);
248 
257  virtual int32_t Send(const struct iovec *sendVector, int32_t nNumItems);
258 
271  virtual int32_t SendFile(int32_t nOutFd, int32_t nInFd, off_t *pOffset, int32_t nCount);
272 
275  bool IsNonblocking(void) {
276  return (m_bIsBlocking == false);
277  };
278 
281  bool SetBlocking(void);
282 
285  bool SetNonblocking(void);
286 
291  uint8_t *GetData(void) {
292  return m_pBuffer;
293  };
294 
298  int32_t GetBytesReceived(void) {
299  return m_nBytesReceived;
300  };
301 
305  int32_t GetBytesSent(void) {
306  return m_nBytesSent;
307  };
308 
324  bool SetOptionLinger(bool bEnable, uint16_t nTime);
325 
330  bool SetOptionReuseAddr();
331 
335  int32_t GetConnectTimeoutSec(void) {
336  return m_stConnectTimeout.tv_sec;
337  };
338 
342  int32_t GetConnectTimeoutUSec(void) {
343  return m_stConnectTimeout.tv_usec;
344  };
345 
356  void SetConnectTimeout(int32_t nConnectTimeoutSec, int32_t nConnectTimeoutUsec = 0)
357  {
358  m_stConnectTimeout.tv_sec = nConnectTimeoutSec;
359  m_stConnectTimeout.tv_usec = nConnectTimeoutUsec;
360  };
361 
365  int32_t GetReceiveTimeoutSec(void) {
366  return m_stRecvTimeout.tv_sec;
367  };
368 
372  int32_t GetReceiveTimeoutUSec(void) {
373  return m_stRecvTimeout.tv_usec;
374  };
375 
386  bool SetReceiveTimeout(int32_t nRecvTimeoutSec, int32_t nRecvTimeoutUsec = 0);
387 
393  bool SetMulticast(bool bEnable, uint8_t multicastTTL = 1);
394 
397  bool GetMulticast() {
398  return m_bIsMulticast;
399  };
400 
403  bool BindInterface(const char *pInterface);
404 
408  int32_t GetSendTimeoutSec(void) {
409  return m_stSendTimeout.tv_sec;
410  };
411 
415  int32_t GetSendTimeoutUSec(void) {
416  return m_stSendTimeout.tv_usec;
417  };
418 
422  bool SetSendTimeout(int32_t nSendTimeoutSec, int32_t nSendTimeoutUsec = 0);
423 
428  CSocketError GetSocketError(void) {
429  return m_socketErrno;
430  };
431 
434  uint32_t GetTotalTimeMs() {
435  return m_timer.GetMilliSeconds();
436  };
437 
440  uint32_t GetTotalTimeUsec() {
441  return m_timer.GetMicroSeconds();
442  };
443 
447  int GetSocketDscp(void);
448 
453  bool SetSocketDscp(int nDscp);
454 
458  return m_socket;
459  };
460 
463  CSocketType GetSocketType() {
464  return m_nSocketType;
465  };
466 
468  void SetSocketType(const CSocketType& type) {
469  m_nSocketType = type;
470  }
471 
474  const char *GetClientAddr() {
475  return inet_ntoa(m_stClientSockaddr.sin_addr);
476  };
477 
480  uint16_t GetClientPort() {
481  return m_stClientSockaddr.sin_port;
482  };
483 
486  const char *GetServerAddr() {
487  return inet_ntoa(m_stServerSockaddr.sin_addr);
488  };
489 
492  uint16_t GetServerPort() {
493  return ntohs(m_stServerSockaddr.sin_port);
494  };
495 
499  uint32_t GetReceiveWindowSize() {
500  return GetWindowSize(SO_RCVBUF);
501  };
502 
506  uint32_t GetSendWindowSize() {
507  return GetWindowSize(SO_SNDBUF);
508  };
509 
513  uint32_t SetReceiveWindowSize(uint32_t nWindowSize) {
514  return SetWindowSize(SO_RCVBUF, nWindowSize);
515  };
516 
520  uint32_t SetSendWindowSize(uint32_t nWindowSize) {
521  return SetWindowSize(SO_SNDBUF, nWindowSize);
522  };
523 
526  bool DisableNagleAlgoritm();
527 
530  bool EnableNagleAlgoritm();
531 
532  virtual bool Open(const char *pAddr, uint16_t nPort){return true;}
533 
534  virtual bool bindport(const char*, uint32_t );
535 
536  virtual bool open();
537 
538  virtual bool isOpen();
539 
540  virtual void closePort();
541 
542  virtual void flush();
543 
544  virtual int waitfordata(size_t data_count,uint32_t timeout = -1, size_t * returned_size = NULL);
545 
546  virtual size_t writeData(const uint8_t * data, size_t size);
547 
548  virtual size_t readData(uint8_t * data, size_t size);
549 
550 
551 protected:
555  m_socketErrno = error;
556  };
557 
560  void SetSocketHandle(SOCKET socket) {
561  m_socket = socket;
562  };
563 
566  bool Flush();
567 
568 private:
571  uint32_t GetWindowSize(uint32_t nOptionName);
572 
575  uint32_t SetWindowSize(uint32_t nOptionName, uint32_t nWindowSize);
576 
577 
587  int32_t Writev(const struct iovec *pVector, size_t nCount);
588 
589 
590 
591  CSimpleSocket *operator=(CSimpleSocket &socket);
592 
593 protected:
594  SOCKET m_socket;
595  CSocketError m_socketErrno;
596  uint8_t *m_pBuffer;
597  int32_t m_nBufferSize;
598  int32_t m_nSocketDomain;
599  CSocketType m_nSocketType;
601  int32_t m_nBytesSent;
602  uint32_t m_nFlags;
605  struct timeval m_stConnectTimeout;
606  struct timeval m_stRecvTimeout;
607  struct timeval m_stSendTimeout;
608  struct sockaddr_in m_stServerSockaddr;
609  struct sockaddr_in m_stClientSockaddr;
610  struct sockaddr_in m_stMulticastGroup;
611  struct linger m_stLinger;
613 #if defined(_WIN32)
614  WSADATA m_hWSAData;
615 #endif
616  fd_set m_writeFds;
617  fd_set m_readFds;
618  fd_set m_errorFds;
619 
620  std::string m_addr;
621  uint32_t m_port;
622  bool m_open;
623 };
624 
625 }
626 
627 
628 #endif /* __SOCKET_H__ */
629 
virtual int32_t SendFile(int32_t nOutFd, int32_t nInFd, off_t *pOffset, int32_t nCount)
Definition: SimpleSocket.cpp:931
Defines socket as IPv6 TCP socket.
Definition: SimpleSocket.h:130
Definition: ActiveSocket.h:48
Shutdown active socket.
Definition: SimpleSocket.h:120
int GetSocketDscp(void)
Definition: SimpleSocket.cpp:294
The connection has been aborted.
Definition: SimpleSocket.h:149
int32_t GetSendTimeoutUSec(void)
Definition: SimpleSocket.h:415
virtual bool Select(void)
Definition: SimpleSocket.h:196
int32_t m_nBufferSize
internal send/receive buffer
Definition: SimpleSocket.h:597
fd_set m_readFds
write file descriptor set
Definition: SimpleSocket.h:617
Defines socket as IPv6 UDP socket.
Definition: SimpleSocket.h:131
int32_t GetBytesReceived(void)
Definition: SimpleSocket.h:298
CStatTimer m_timer
linger flag
Definition: SimpleSocket.h:612
Connection was forcibly closed by the remote host.
Definition: SimpleSocket.h:153
uint16_t GetClientPort()
Definition: SimpleSocket.h:480
int32_t GetBytesSent(void)
Definition: SimpleSocket.h:305
uint8_t * GetData(void)
Definition: SimpleSocket.h:291
CSocketType
Defines the socket types defined by CSimpleSocket class.
Definition: SimpleSocket.h:125
Socket is non-blocking and the connection cannot be completed immediately.
Definition: SimpleSocket.h:147
Operation would block if socket were blocking.
Definition: SimpleSocket.h:145
CSocketError GetSocketError(void)
Definition: SimpleSocket.h:428
struct sockaddr_in m_stMulticastGroup
client address
Definition: SimpleSocket.h:610
virtual bool IsSocketValid(void)
Definition: SimpleSocket.h:215
bool SetMulticast(bool bEnable, uint8_t multicastTTL=1)
Definition: SimpleSocket.cpp:245
Definition: ChannelDevice.h:4
uint32_t GetReceiveWindowSize()
Definition: SimpleSocket.h:499
bool EnableNagleAlgoritm()
Definition: SimpleSocket.cpp:391
Definition: SimpleSocket.h:114
Invalid socket handle.
Definition: SimpleSocket.h:140
void SetSocketError(CSimpleSocket::CSocketError error)
Definition: SimpleSocket.h:554
virtual bool Shutdown(CShutdownMode nShutdown)
Definition: SimpleSocket.cpp:523
Firewall rules forbid connection.
Definition: SimpleSocket.h:151
Generic socket error translates to error below.
Definition: SimpleSocket.h:138
uint8_t * m_pBuffer
number of last error
Definition: SimpleSocket.h:596
int32_t GetConnectTimeoutUSec(void)
Definition: SimpleSocket.h:342
int32_t m_nBytesReceived
socket type - UDP, TCP or RAW
Definition: SimpleSocket.h:600
std::string m_addr
error file descriptor set
Definition: SimpleSocket.h:620
int32_t m_nSocketDomain
size of internal send/receive buffer
Definition: SimpleSocket.h:598
struct sockaddr_in m_stClientSockaddr
server address
Definition: SimpleSocket.h:609
CShutdownMode
Defines the three possible states for shuting down a socket.
Definition: SimpleSocket.h:117
int32_t m_nBytesSent
number of bytes received
Definition: SimpleSocket.h:601
const char * GetServerAddr()
Definition: SimpleSocket.h:486
Unknown error please report to mark@carrierlabs.com.
Definition: SimpleSocket.h:156
struct sockaddr_in m_stServerSockaddr
send timeout
Definition: SimpleSocket.h:608
bool SetSocketDscp(int nDscp)
Definition: SimpleSocket.cpp:270
Shutdown both active and passive sockets.
Definition: SimpleSocket.h:121
The receive buffer point outside the process&#39;s address space.
Definition: SimpleSocket.h:152
Invalid protocol for operation.
Definition: SimpleSocket.h:150
uint32_t m_nFlags
number of bytes sent
Definition: SimpleSocket.h:602
bool SetNonblocking(void)
Definition: SimpleSocket.cpp:855
int32_t GetReceiveTimeoutUSec(void)
Definition: SimpleSocket.h:372
CSocketType GetSocketType()
Definition: SimpleSocket.h:463
struct linger m_stLinger
multicast group to bind to
Definition: SimpleSocket.h:611
bool BindInterface(const char *pInterface)
Definition: SimpleSocket.cpp:220
bool Flush()
Definition: SimpleSocket.cpp:539
virtual int32_t Send(const uint8_t *pBuf, size_t bytesToSend)
Definition: SimpleSocket.cpp:414
bool SetOptionLinger(bool bEnable, uint16_t nTime)
Definition: SimpleSocket.cpp:705
int32_t GetReceiveTimeoutSec(void)
Definition: SimpleSocket.h:365
Invalid socket type.
Definition: SimpleSocket.h:127
Timed out while attempting operation.
Definition: SimpleSocket.h:144
bool GetMulticast()
Definition: SimpleSocket.h:397
void SetSocketHandle(SOCKET socket)
Definition: SimpleSocket.h:560
SOCKET GetSocketDescriptor()
Definition: SimpleSocket.h:457
CSocketType m_nSocketType
socket type PF_INET, PF_INET6
Definition: SimpleSocket.h:599
virtual bool Close(void)
Definition: SimpleSocket.cpp:490
Defines socket as TCP socket.
Definition: SimpleSocket.h:128
bool SetOptionReuseAddr()
Definition: SimpleSocket.cpp:684
void SetSocketType(const CSocketType &type)
set socket descriptor
Definition: SimpleSocket.h:468
uint32_t SetSendWindowSize(uint32_t nWindowSize)
Definition: SimpleSocket.h:520
Shutdown passive socket.
Definition: SimpleSocket.h:119
Pointer type supplied as argument is invalid.
Definition: SimpleSocket.h:155
Invalid destination address specified.
Definition: SimpleSocket.h:141
Provides raw network protocol access.
Definition: SimpleSocket.h:132
No server is listening at remote address.
Definition: SimpleSocket.h:143
Address already in use.
Definition: SimpleSocket.h:154
static const char * DescribeError(CSocketError err)
Definition: SimpleSocket.cpp:1099
fd_set m_errorFds
read file descriptor set
Definition: SimpleSocket.h:618
const char * GetClientAddr()
Definition: SimpleSocket.h:474
Invalid destination port specified.
Definition: SimpleSocket.h:142
bool m_bIsMulticast
is socket blocking
Definition: SimpleSocket.h:604
virtual bool Initialize(void)
Definition: SimpleSocket.cpp:189
Call was interrupted by a signal that was caught before a valid connection arrived.
Definition: SimpleSocket.h:148
uint32_t GetSendWindowSize()
Definition: SimpleSocket.h:506
uint32_t SetReceiveWindowSize(uint32_t nWindowSize)
Definition: SimpleSocket.h:513
void TranslateSocketError(void)
Definition: SimpleSocket.cpp:973
bool DisableNagleAlgoritm()
Definition: SimpleSocket.cpp:368
struct timeval m_stConnectTimeout
is the UDP socket multicast;
Definition: SimpleSocket.h:605
bool SetBlocking(void)
Definition: SimpleSocket.cpp:894
CSocketError m_socketErrno
socket handle
Definition: SimpleSocket.h:595
int32_t GetConnectTimeoutSec(void)
Definition: SimpleSocket.h:335
void SetConnectTimeout(int32_t nConnectTimeoutSec, int32_t nConnectTimeoutUsec=0)
Definition: SimpleSocket.h:356
bool SetSendTimeout(int32_t nSendTimeoutSec, int32_t nSendTimeoutUsec=0)
Definition: SimpleSocket.cpp:657
bool m_bIsBlocking
socket flags
Definition: SimpleSocket.h:603
Definition: StatTimer.h:70
int32_t GetSendTimeoutSec(void)
Definition: SimpleSocket.h:408
Currently not connected.
Definition: SimpleSocket.h:146
virtual int32_t Receive(int32_t nMaxBytes=1, uint8_t *pBuffer=0)
Definition: SimpleSocket.cpp:732
struct timeval m_stSendTimeout
receive timeout
Definition: SimpleSocket.h:607
uint32_t GetTotalTimeMs()
Definition: SimpleSocket.h:434
bool IsNonblocking(void)
Definition: SimpleSocket.h:275
No socket error.
Definition: SimpleSocket.h:139
bool SetReceiveTimeout(int32_t nRecvTimeoutSec, int32_t nRecvTimeoutUsec=0)
Definition: SimpleSocket.cpp:629
uint32_t GetTotalTimeUsec()
Definition: SimpleSocket.h:440
CSocketError
Defines all error codes handled by the CSimpleSocket class.
Definition: SimpleSocket.h:136
struct timeval m_stRecvTimeout
connection timeout
Definition: SimpleSocket.h:606
Defines socket as UDP socket.
Definition: SimpleSocket.h:129
fd_set m_writeFds
internal statistics.
Definition: SimpleSocket.h:616
uint16_t GetServerPort()
Definition: SimpleSocket.h:492