TCPSocket.cpp
Go to the documentation of this file.
1 // ****************************************************************************
2 // This file is part of the Integrating Vision Toolkit (IVT).
3 //
4 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
5 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
6 //
7 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
8 // 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 are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright
17 // notice, this list of conditions and the following disclaimer in the
18 // documentation and/or other materials provided with the distribution.
19 //
20 // 3. Neither the name of the KIT nor the names of its contributors may be
21 // used to endorse or promote products derived from this software
22 // without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
25 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
28 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // ****************************************************************************
35 // ****************************************************************************
36 // Filename: TCPSocket.cpp
37 // Author: Florian Hecht
38 // Date: 08.01.2009
39 // ****************************************************************************
40 
41 #include <new> // for explicitly using correct new/delete operators on VC DSPs
42 
43 #include "TCPSocket.h"
44 
45 #include <stdio.h>
46 #ifndef __TI_COMPILER_VERSION__
47 #include <memory.h>
48 #endif
49 
50 #include <stdlib.h>
51 #include <errno.h>
52 
53 
54 #if defined(WIN32)
55 #define _WINSOCKAPI_
56 #include <windows.h>
57 #include <winsock2.h>
58 
59 static int socket_ref_count = 0;
60 
61 void InitWinSock()
62 {
63  socket_ref_count++;
64 
65  if (socket_ref_count > 1)
66  return;
67 
68  WORD wVersionRequested;
69  WSADATA wsaData;
70  int wsaerr;
71 
72  wVersionRequested = MAKEWORD(2, 0);
73  wsaerr = WSAStartup(wVersionRequested, &wsaData);
74  if (wsaerr != 0)
75  {
76  // Tell the user that we couldn't find the WinSock DLL
77  printf("Error: couldn't initialize WinSock!\n");
78  }
79 
80  return;
81 }
82 
83 void ShutdownWinSock()
84 {
85  socket_ref_count--;
86  if (socket_ref_count > 0)
87  return;
88 
89  WSACleanup();
90 }
91 
92 #elif defined(__TI_COMPILER_VERSION__)
93 #include <string.h>
94 #include "Networking/VCNet.h"
95 #else
96 #include <unistd.h>
97 #include <signal.h>
98 #include <fcntl.h>
99 #include <sys/socket.h>
100 #include <sys/types.h>
101 #include <netdb.h>
102 #include <netinet/ip.h>
103 #include <netinet/tcp.h>
104 #endif
105 
106 
107 
108 CTCPSocket::CTCPSocket() : m_socket(-1), m_bListening(false)
109 {
110 #ifdef WIN32
111  InitWinSock();
112 #endif
113 }
114 
116 {
117  Close();
118 
119 #ifdef WIN32
120  ShutdownWinSock();
121 #endif
122 }
123 
124 bool CTCPSocket::Listen(const unsigned char *ip, int port)
125 {
126  Close();
127 
128 #ifdef WIN32
129  SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
130  if (sock == INVALID_SOCKET)
131  {
132  m_socket = -1;
133  return false;
134  }
135 
136  m_socket = (int)sock;
137 
138  // set linger on - helps in closing socket immidiately
139  linger li;
140  li.l_onoff = true;
141  li.l_linger = 0;
142 
143  if(setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*)&li, sizeof(li)) == -1)
144  {
145  printf("setting linger option failed\n");
146  Close();
147  return false;
148  }
149 
150  // set non blocking
151  u_long v = 1;
152  if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR)
153  {
154  printf("setting non-blocking option failed\n");
155  Close();
156  return false;
157  }
158 
159  struct sockaddr_in serv_addr;
160  memset((char *)&serv_addr, 0, sizeof(serv_addr));
161 
162  serv_addr.sin_family = AF_INET;
163  if (ip != NULL)
164  {
165  memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4);
166  }
167  else
168  {
169  serv_addr.sin_addr.s_addr = INADDR_ANY;
170  }
171  serv_addr.sin_port = htons(port);
172 
173  if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
174  {
175  Close();
176  return false;
177  }
178 
179  listen(sock, 5);
180  m_bListening = true;
181 
182 #elif defined(__TI_COMPILER_VERSION__)
183  uint_32 error;
184 
185  m_socket = socket_stream();
186  if (m_socket == VCRT_SOCKET_ERROR)
187  {
188  m_socket = -1;
189  return false;
190  }
191 
192  //set linger on - helps in closing socket immidiately
193 
194  // SO_LINGER socket option is not available on VCRT.
195  // But in Close() the shutdown flag FLAG_ABORT_CONNECTION enforces hard closing of the socket
196  // as would SO_LINGER with zero timeout on other platforms.
197 
198  //set non blocking
199 
200  // there is no socket-global (non-)blocking flag on VCRT
201  // - accept() is always blocking and therefore guarded by VCRT_selectset().
202  // - recv() behavior is set during Recv() depending on bWait flag
203  // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms
204  uint_32 opt_value = TRUE;
205  error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value));
206  if (error != VCRT_OK)
207  {
208  printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error);
209  Close();
210  return false;
211  }
212 
213  sockaddr_in serv_addr;
214  memset( &serv_addr, 0, sizeof(serv_addr));
215  serv_addr.sin_family = AF_INET;
216  if (ip != NULL)
217  {
218  //never cast ip to an int pointer! this would imply 4byte alignment.
219  memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4);
220  // vcrt expects inverse order of ip chars
221  // than provided by RemoteApplicationHandler.cpp
222  serv_addr.sin_addr.s_addr = revert_byte_order(serv_addr.sin_addr.s_addr);
223  }
224  else
225  {
226  serv_addr.sin_addr.s_addr = INADDR_ANY;
227  }
228  serv_addr.sin_port = port; //htons(port); VCRT does not want the port in network byte order
229 
230  error = bind(m_socket, &serv_addr, sizeof(serv_addr));
231  if (error!=VCRT_OK)
232  {
233  printf("\nsocket bind failed, error code: 0x%x\n", error);
234  Close();
235  return false;
236  }
237 
238  error = listen(m_socket, 5);
239  if (error!=VCRT_OK)
240  {
241  printf("\nsocket listen failed, error code: 0x%x\n", error);
242  Close();
243  return false;
244  }
245  m_bListening = true;
246 
247 #else
248  m_socket = socket(AF_INET, SOCK_STREAM, 0);
249  if (m_socket < 0)
250  {
251  m_socket = -1;
252  return false;
253  }
254 
255  // set linger on - helps in closing socket immidiately
256  linger li;
257  li.l_onoff = true;
258  li.l_linger = 0;
259 
260  if(setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &li, sizeof(li)) == -1)
261  {
262  printf("setting linger option failed\n");
263  Close();
264  return false;
265  }
266 
267  // set non blocking
268  if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1)
269  {
270  printf("setting non-blocking option failed\n");
271  Close();
272  return false;
273  }
274 
275  struct sockaddr_in serv_addr;
276  bzero((char *)&serv_addr, sizeof(serv_addr));
277 
278  serv_addr.sin_family = AF_INET;
279  if (ip != NULL)
280  {
281  bcopy(ip, (char *)&serv_addr.sin_addr.s_addr, 4);
282  }
283  else
284  {
285  serv_addr.sin_addr.s_addr = INADDR_ANY;
286  }
287  serv_addr.sin_port = htons(port);
288 
289  if (bind(m_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
290  {
291  Close();
292  return false;
293  }
294 
295  listen(m_socket, 5);
296  m_bListening = true;
297 #endif
298 
299  return true;
300 }
301 
302 CTCPSocket* CTCPSocket::Accept(unsigned char *ip)
303 {
304  if (m_socket == -1 || !m_bListening)
305  return NULL;
306 
307 #ifdef WIN32
308  SOCKET sock = (SOCKET)m_socket;
309  struct sockaddr_in cli_addr;
310  int clilen = sizeof(cli_addr);
311 
312  SOCKET new_socket = accept(sock, (struct sockaddr *) &cli_addr, &clilen);
313  if (new_socket == INVALID_SOCKET)
314  {
315  return NULL;
316  }
317 
318  // set non blocking
319  u_long v = 1;
320  if (ioctlsocket(new_socket, FIONBIO, &v) == SOCKET_ERROR)
321  {
322  printf("setting non-blocking option failed\n");
323  Close();
324  return false;
325  }
326 
327  // set no delay for sending
328  int v2 = 1;
329  if (setsockopt(new_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&v2, sizeof(v2)) == -1)
330  {
331  printf("newly accepted socket couldn't be set to no delay mode\n");
332  }
333 
334  if (ip != NULL)
335  {
336  memcpy(ip, (char *) &cli_addr.sin_addr.s_addr, 4);
337  }
338 
339  CTCPSocket *s = new CTCPSocket();
340  s->m_socket = (int) new_socket;
341 
342  return s;
343 
344 #elif defined(__TI_COMPILER_VERSION__)
345  uint_32 error;
346 
347  // acccept is always blocking on vcrt, so we need to test for activity first
348  // which is not blocking
349  error = VCRT_selectset(&m_socket, 1, (uint_32)-1);
350 
351  if (error==0) //no new connections, nothing to do
352  {
353  return NULL;
354  }
355  if (error==VCRT_SOCKET_ERROR) //an error occured
356  {
357  printf("Error in accept(): VCRT_selectset failed, error code 0x%x\n", VCRT_geterror(m_socket));
358  return NULL;
359  }
360  if (error!=m_socket) //should never happen as we check only this socket.
361  {
362  printf("Error in accept(): VCRT_selectset returned invalid socket");
363  return NULL;
364  }
365 
366 
367  sockaddr_in cli_addr;
368  uint_16 clilen = sizeof(cli_addr);
369 
370  int new_socket = accept(m_socket, &cli_addr, &clilen);
371  if (new_socket == VCRT_SOCKET_ERROR)
372  {
373  error = VCRT_geterror(m_socket);
374  if (error == VCRT_OK)
375  {
376  printf("\nAccept: Connection reset by peer");
377  }
378  else
379  {
380  printf("Error, accept() failed with error code 0x%x\n", error);
381  }
382  return NULL;
383  }
384 
385 
386 
387  // set non blocking
388 
389  // there is no socket-global (non-)blocking flag on VCRT
390  // - accept() is always blocking and therefore guarded by VCRT_selectset().
391  // - recv() behavior is set during Recv() depending on bWait flag
392  // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms
393  uint_32 opt_value;
394 
395  opt_value = TRUE;
396  error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value));
397  if (error != VCRT_OK)
398  {
399  printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error);
400  }
401 
402 
403 
404  // set no delay for sending
405  // OPT_NO_NAGLE_ALGORITHM is the VCRT equivalent to TCP_NODELAY
406  opt_value = TRUE;
407  error = setsockopt(m_socket, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &opt_value, sizeof(opt_value));
408  if (error != VCRT_OK)
409  {
410  printf("Error, setsockopt(OPT_NO_NAGLE_ALGORITHM) failed with error code 0x%x\n", error);
411  }
412 
413 
414 
415  if (ip != NULL)
416  {
417  // vcrt expects inverse order of ip chars
418  // than provided by RemoteApplicationHandler.cpp
419  cli_addr.sin_addr.s_addr = revert_byte_order(cli_addr.sin_addr.s_addr);
420  //never cast ip to an int pointer! this would imply 4byte alignment.
421  memcpy( ip, &cli_addr.sin_addr.s_addr, 4);
422  }
423 
424  CTCPSocket *sock = new CTCPSocket();
425  sock->m_socket = new_socket;
426 
427  return sock;
428 
429 #else
430  struct sockaddr_in cli_addr;
431  socklen_t clilen = sizeof(cli_addr);
432 
433  int new_socket = accept(m_socket, (struct sockaddr *) &cli_addr, &clilen);
434  if (new_socket < 0)
435  {
436  return NULL;
437  }
438 
439  // set non blocking
440  if (fcntl(new_socket, F_SETFL, O_NONBLOCK) == -1)
441  {
442  printf("newly accepted socket couldn't be set to non blocking mode\n");
443  }
444 
445  // set no delay for sending
446  int v = 1;
447  if (setsockopt(new_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)) == -1)
448  {
449  printf("newly accepted socket couldn't be set to no delay mode\n");
450  }
451 
452  if (ip != NULL)
453  {
454  bcopy((char *)&cli_addr.sin_addr.s_addr, ip, 4);
455  }
456 
457  CTCPSocket *sock = new CTCPSocket();
458  sock->m_socket = new_socket;
459 
460  return sock;
461 #endif
462 }
463 
464 bool CTCPSocket::Open(const unsigned char *ip, int port)
465 {
466  Close();
467 
468 #ifdef WIN32
469  SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
470  if (sock == INVALID_SOCKET)
471  {
472  m_socket = -1;
473  return false;
474  }
475 
476  m_socket = (int)sock;
477 
478  struct sockaddr_in serv_addr;
479  memset((char *)&serv_addr, 0, sizeof(serv_addr));
480 
481  serv_addr.sin_family = AF_INET;
482  memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4);
483  serv_addr.sin_port = htons(port);
484 
485  if (connect(sock, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
486  {
487  Close();
488  return false;
489  }
490 
491  // set non blocking (after connect)
492  u_long v = 1;
493  if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR)
494  {
495  printf("setting non-blocking option failed\n");
496  Close();
497  return false;
498  }
499 
500  // set no delay for sending
501  int v2 = 1;
502  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&v2, sizeof(v2)) == -1)
503  {
504  printf("socket couldn't be set to no delay mode\n");
505  }
506 
507  m_bListening = false;
508 
509 #elif defined(__TI_COMPILER_VERSION__)
510  uint_32 error;
511 
512  m_socket = socket_stream();
513  if (m_socket == VCRT_SOCKET_ERROR)
514  {
515  printf("Error in Open(): socket_stream() failed\n");
516  m_socket = -1;
517  return false;
518  }
519 
520  sockaddr_in serv_addr;
521  memset( &serv_addr, 0, sizeof(serv_addr));
522  serv_addr.sin_family = AF_INET;
523 
524  //never cast ip to an int pointer! this would imply 4byte alignment.
525  memcpy(&(serv_addr.sin_addr.s_addr), ip, 4);
526  // vcrt expects inverse order of ip chars
527  // than provided by RemoteApplicationHandler.cpp
528  serv_addr.sin_addr.s_addr = revert_byte_order(serv_addr.sin_addr.s_addr);
529 
530  serv_addr.sin_port = port; //htons(port); VCRT does not want the port in network byte order
531 
532  //printf("DEBUG: chars %d,%d,%d,%d, serv_addr.sin_addr.s_addr: 0x%x\n", ip[0], ip[1], ip[2], ip[3], serv_addr.sin_addr.s_addr);
533 
534  error = connect(m_socket, &serv_addr, sizeof(serv_addr));
535  if (error != VCRT_OK)
536  {
537  printf("Error in Open(): connect failed, error code 0x%x\n", error);
538  Close();
539  return false;
540  }
541 
542  // set non blocking (after connect)
543 
544  // there is no socket-global (non-)blocking flag on VCRT
545  // - accept() is always blocking and therefore guarded by VCRT_selectset().
546  // - recv() behavior is set during Recv() depending on bWait flag
547  // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms
548  uint_32 opt_value;
549 
550  opt_value = TRUE;
551  error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value));
552  if (error != VCRT_OK)
553  {
554  printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error);
555  Close();
556  return false;
557  }
558 
559 
560  // set no delay for sending
561  // OPT_NO_NAGLE_ALGORITHM is the VCRT equivalent to TCP_NODELAY
562  opt_value = TRUE;
563  error = setsockopt(m_socket, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &opt_value, sizeof(opt_value));
564  if (error != VCRT_OK)
565  {
566  printf("Error, setsockopt(OPT_NO_NAGLE_ALGORITHM) failed with error code 0x%x\n", error);
567  Close();
568  return false;
569  }
570 
571  m_bListening = false;
572 
573 #else
574  m_socket = socket(AF_INET, SOCK_STREAM, 0);
575  if (m_socket < 0)
576  {
577  m_socket = -1;
578  return false;
579  }
580 
581  struct sockaddr_in serv_addr;
582  bzero((char *)&serv_addr, sizeof(serv_addr));
583 
584  serv_addr.sin_family = AF_INET;
585  bcopy(ip, (char *)&serv_addr.sin_addr.s_addr, 4);
586  serv_addr.sin_port = htons(port);
587 
588  if (connect(m_socket, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
589  {
590  Close();
591  return false;
592  }
593 
594  // set non blocking (after connect)
595  if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1)
596  {
597  Close();
598  return false;
599  }
600 
601  // set no delay for sending
602  int v = 1;
603  if (setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)) == -1)
604  {
605  Close();
606  return false;
607  }
608 
609  m_bListening = false;
610 #endif
611 
612  return true;
613 }
614 
616 {
617  if (m_socket == -1)
618  return;
619 
620 #ifdef WIN32
621  SOCKET sock = (SOCKET)m_socket;
622  closesocket(sock);
623 
624 #elif defined(__TI_COMPILER_VERSION__)
625  // FLAG_ABORT_CONNECTION enforces hard closing of the socket as specified
626  // by the SO_LINGER socket option with zero timeout on other platforms.
627  // SO_LINGER is not available on VCRT.
628  uint_32 error = shutdown(m_socket, FLAG_ABORT_CONNECTION);
629  if(error!= VCRT_OK)
630  {
631  printf("\nsocket shutdown failed, error code: 0x%x\n", error);
632  }
633 #else
634  close(m_socket);
635 #endif
636 
637  m_socket = -1;
638 }
639 
640 bool CTCPSocket::Send(const void *pData, int nBytes)
641 {
642  if (m_socket == -1 || m_bListening)
643  return false;
644 
645 #ifdef WIN32
646  SOCKET sock = (SOCKET)m_socket;
647  int size = 0;
648  unsigned char *ptr = (unsigned char*) pData;
649  while (true)
650  {
651  int s = send(sock, (const char *) ptr, nBytes, 0);
652  if (s == SOCKET_ERROR)
653  {
654  int errnum = WSAGetLastError();
655  if (errnum == WSAEWOULDBLOCK)
656  continue;
657 
658  return false;
659  }
660 
661  size += s;
662  ptr += s;
663  nBytes -= s;
664  if (nBytes == 0)
665  break;
666 
667  }
668 
669 #elif defined(__TI_COMPILER_VERSION__)
670 
671  char *ptr = (char *) pData;
672  while (nBytes>0)
673  {
674  // as OPT_SEND_NOWAIT is set above, this blocks until data is buffered
675  // but does not wait for data to be send and acknowledged.
676  // Send() therefore blocks until all data is passed on to the OS.
677  int_32 count = send(m_socket, ptr, nBytes, 0);
678 
679  if (count==VCRT_ERROR)
680  {
681  printf("Error in Send(): send failed, error code 0x%x\n", VCRT_geterror(m_socket));
682  return false;
683  }
684 
685  ptr += count;
686  nBytes -= count;
687  }
688 
689 #else
690  int size = 0;
691  unsigned char *ptr = (unsigned char *) pData;
692  while (true)
693  {
694  int s = write(m_socket, ptr, nBytes);
695  if (s == -1)
696  {
697  int errnum = errno;
698  if (errnum == EAGAIN)
699  continue;
700 
701  return false;
702  }
703 
704  size += s;
705  ptr += s;
706  nBytes -= s;
707  if (nBytes == 0)
708  break;
709 
710  }
711 #endif
712 
713  return true;
714 }
715 
716 int CTCPSocket::Recv(void *pData, int nMaxBytes, bool bWait)
717 {
718  if (m_socket == -1 || m_bListening)
719  return -1;
720 
721 #ifdef WIN32
722  SOCKET sock = (SOCKET) m_socket;
723 
724  if (bWait)
725  {
726  int size = 0;
727  unsigned char *ptr = (unsigned char*) pData;
728  while (true)
729  {
730  int s = recv(sock, (char *) ptr, nMaxBytes, 0);
731  if (s == SOCKET_ERROR)
732  {
733  int errnum = WSAGetLastError();
734  if (errnum == WSAEWOULDBLOCK)
735  continue;
736 
737  // this is really bad, the connection is probably dead
738  return -1;
739  }
740 
741  ptr += s;
742  size += s;
743  nMaxBytes -= s;
744 
745  if (nMaxBytes == 0)
746  return size;
747 
748  }
749  }
750  else
751  {
752  int size = recv(sock, (char *) pData, nMaxBytes, 0);
753  if (size == SOCKET_ERROR)
754  {
755  int errnum = WSAGetLastError();
756  if (errnum == WSAEWOULDBLOCK)
757  return 0;
758 
759  // this is really bad, the connection is probably dead
760 
761  return -1;
762  }
763  else if (size == 0)
764  {
765  return -1;
766  }
767 
768  return size;
769  }
770 
771 #elif defined(__TI_COMPILER_VERSION__)
772  //set OPT_RECV_NOWAIT depending on bWait
773  // if bWait==false: behaves like a non-blocking socket on other platforms
774  // else: recv() blocks, avoiding polling with busy waiting.
775  // recv() may non the less return early in case of a PUSH flag.
776  uint_32 opt_value = bWait? FALSE : TRUE;
777  uint_32 error = setsockopt(m_socket, SOL_TCP, OPT_RECEIVE_NOWAIT, &opt_value, sizeof(opt_value));
778  if (error != VCRT_OK)
779  {
780  printf("Error in Recv(), setsockopt(OPT_RECEIVE_NOWAIT) failed with error code 0x%x\n", error);
781  return -1;
782  }
783 
784  if (bWait)
785  {
786  int size = 0;
787  char *ptr = (char *) pData;
788  while (nMaxBytes>0)
789  {
790  int_32 count = recv(m_socket, ptr, nMaxBytes, 0); //is set to blocking above
791 
792  if (count == VCRT_ERROR)
793  {
794  printf("Error in Recv(): recv failed, error code 0x%x\n", VCRT_geterror(m_socket));
795  // this is really bad, the connection is probably dead
796  return -1;
797  }
798 
799  ptr += count;
800  size += count;
801  nMaxBytes -= count;
802  }
803  return size;
804  }
805  else
806  {
807  //receive whatever data is available and return immediately
808  int_32 count = recv(m_socket, (char*)pData, nMaxBytes, 0); //is set to non-blocking above
809 
810  if (count == VCRT_ERROR)
811  {
812  printf("Error in Recv(): recv failed, error code 0x%x\n", VCRT_geterror(m_socket));
813  // this is really bad, the connection is probably dead
814  return -1;
815  }
816  // on vcrt, count==0 means zero bytes received and not connection closed by peer.
817  // so in this case 0 is returned and not -1.
818 
819  return count;
820  }
821 
822 #else
823  if (bWait)
824  {
825  int size = 0;
826  unsigned char *ptr = (unsigned char *) pData;
827  while (true)
828  {
829  int s = (int) recv(m_socket, ptr, nMaxBytes, 0);
830  if (s == -1)
831  {
832  int errnum = errno;
833  if (errnum == EAGAIN)
834  continue;
835 
836  // this is really bad, the connection is probably dead
837 
838  return -1;
839  }
840 
841  ptr += s;
842  size += s;
843  nMaxBytes -= s;
844 
845  if (nMaxBytes == 0)
846  return size;
847 
848  }
849  }
850  else
851  {
852  int size = (int) recv(m_socket, pData, nMaxBytes, 0);
853  if (size == -1)
854  {
855  int errnum = errno;
856  if (errnum == EAGAIN)
857  return 0;
858 
859  // this is really bad, the connection is probably dead
860 
861  return -1;
862  }
863  else if (size == 0)
864  {
865  return -1;
866  }
867 
868  return size;
869  }
870 #endif
871 
872  return -1;
873 }
int Recv(void *pData, int nMaxBytes, bool bWait=false)
Definition: TCPSocket.cpp:716
GLfloat GLfloat GLfloat v2
Definition: glext.h:3532
void Close()
Definition: TCPSocket.cpp:615
bool Listen(const unsigned char *ip=0, int port=0)
Definition: TCPSocket.cpp:124
GLdouble s
Definition: glext.h:3211
CTCPSocket * Accept(unsigned char *ip=0)
Definition: TCPSocket.cpp:302
bool m_bListening
Definition: TCPSocket.h:90
uint32_t revert_byte_order(uint32_t dword)
Definition: VCNet.h:65
bool Open(const unsigned char *ip, int port)
Definition: TCPSocket.cpp:464
int m_socket
Definition: TCPSocket.h:89
bool Send(const void *pData, int nBytes)
Definition: TCPSocket.cpp:640
GLsizeiptr size
Definition: glext.h:3388
GLuint GLuint GLsizei count
Definition: glext.h:3121
const GLdouble * v
Definition: glext.h:3212
uint16_t htons(uint16_t hostshort)
Definition: VCNet.h:79


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Mon Dec 2 2019 03:47:28