TCPSocket.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  TCPSocket.cpp
00037 // Author:    Florian Hecht
00038 // Date:      08.01.2009
00039 // ****************************************************************************
00040 
00041 #include <new> // for explicitly using correct new/delete operators on VC DSPs
00042 
00043 #include "TCPSocket.h"
00044 
00045 #include <stdio.h>
00046 #ifndef __TI_COMPILER_VERSION__
00047 #include <memory.h>
00048 #endif
00049 
00050 #include <stdlib.h>
00051 #include <errno.h>
00052 
00053 
00054 #if defined(WIN32)
00055 #define _WINSOCKAPI_
00056 #include <windows.h>
00057 #include <winsock2.h>
00058 
00059 static int socket_ref_count = 0;
00060 
00061 void InitWinSock()
00062 {
00063         socket_ref_count++;
00064 
00065         if (socket_ref_count > 1)
00066                 return;
00067 
00068         WORD wVersionRequested;
00069         WSADATA wsaData;
00070         int wsaerr;
00071 
00072         wVersionRequested = MAKEWORD(2, 0);
00073         wsaerr = WSAStartup(wVersionRequested, &wsaData);
00074         if (wsaerr != 0)
00075         {
00076                 // Tell the user that we couldn't find the WinSock DLL
00077                 printf("Error: couldn't initialize WinSock!\n");
00078         }
00079 
00080         return;
00081 }
00082 
00083 void ShutdownWinSock()
00084 {
00085         socket_ref_count--;
00086         if (socket_ref_count > 0)
00087                 return;
00088 
00089         WSACleanup();
00090 }
00091 
00092 #elif defined(__TI_COMPILER_VERSION__)
00093 #include <string.h>
00094 #include "Networking/VCNet.h"
00095 #else
00096 #include <unistd.h>
00097 #include <signal.h>
00098 #include <fcntl.h>
00099 #include <sys/socket.h>
00100 #include <sys/types.h>
00101 #include <netdb.h>
00102 #include <netinet/ip.h>
00103 #include <netinet/tcp.h>
00104 #endif
00105 
00106 
00107 
00108 CTCPSocket::CTCPSocket() : m_socket(-1), m_bListening(false)
00109 {
00110 #ifdef WIN32
00111         InitWinSock();
00112 #endif
00113 }
00114 
00115 CTCPSocket::~CTCPSocket()
00116 {
00117         Close();
00118 
00119 #ifdef WIN32
00120         ShutdownWinSock();
00121 #endif
00122 }
00123 
00124 bool CTCPSocket::Listen(const unsigned char *ip, int port)
00125 {
00126         Close();
00127         
00128 #ifdef WIN32
00129         SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
00130         if (sock == INVALID_SOCKET)
00131         {
00132                 m_socket = -1;
00133                 return false;
00134         }
00135 
00136         m_socket = (int)sock;
00137 
00138         // set linger on - helps in closing socket immidiately
00139         linger li;
00140         li.l_onoff = true;
00141         li.l_linger = 0;
00142         
00143         if(setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*)&li, sizeof(li)) == -1)
00144         {
00145                 printf("setting linger option failed\n");
00146                 Close();
00147                 return false;
00148         }
00149 
00150         // set non blocking
00151         u_long v = 1;
00152         if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR)
00153         {
00154                 printf("setting non-blocking option failed\n");
00155                 Close();
00156                 return false;
00157         }
00158 
00159         struct sockaddr_in serv_addr;
00160         memset((char *)&serv_addr, 0, sizeof(serv_addr));
00161         
00162         serv_addr.sin_family = AF_INET;
00163         if (ip != NULL)
00164         {
00165                 memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4);
00166         }
00167         else
00168         {
00169                 serv_addr.sin_addr.s_addr = INADDR_ANY;
00170         }
00171         serv_addr.sin_port = htons(port);
00172         
00173         if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
00174         {
00175                 Close();
00176                 return false;
00177         }
00178         
00179         listen(sock, 5);
00180         m_bListening = true;
00181 
00182 #elif defined(__TI_COMPILER_VERSION__)
00183         uint_32 error;
00184         
00185         m_socket = socket_stream();
00186         if (m_socket == VCRT_SOCKET_ERROR) 
00187         {
00188                 m_socket = -1;
00189                 return false;
00190         }
00191         
00192         //set linger on - helps in closing socket immidiately
00193 
00194         // SO_LINGER socket option is not available on VCRT.
00195         // But in Close() the shutdown flag FLAG_ABORT_CONNECTION enforces hard closing of the socket
00196         // as would SO_LINGER with zero timeout on other platforms.
00197         
00198         //set non blocking
00199 
00200         // there is no socket-global (non-)blocking flag on VCRT
00201         // - accept() is always blocking and therefore guarded by VCRT_selectset().
00202         // - recv() behavior is set during Recv() depending on bWait flag
00203         // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms
00204         uint_32 opt_value = TRUE;
00205         error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value));
00206         if (error != VCRT_OK)
00207         {
00208                 printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error);
00209                 Close();
00210                 return false;
00211         }
00212         
00213         sockaddr_in serv_addr;
00214         memset( &serv_addr, 0, sizeof(serv_addr));
00215         serv_addr.sin_family      = AF_INET;
00216         if (ip != NULL)
00217         {
00218                 //never cast ip to an int pointer! this would imply 4byte alignment.
00219                 memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4);
00220                 // vcrt expects inverse order of ip chars
00221                 // than provided by RemoteApplicationHandler.cpp
00222                 serv_addr.sin_addr.s_addr = revert_byte_order(serv_addr.sin_addr.s_addr);
00223         }
00224         else
00225         {
00226                 serv_addr.sin_addr.s_addr = INADDR_ANY;
00227         }
00228         serv_addr.sin_port = port; //htons(port); VCRT does not want the port in network byte order
00229         
00230         error = bind(m_socket, &serv_addr, sizeof(serv_addr));
00231         if (error!=VCRT_OK)
00232         {
00233                 printf("\nsocket bind failed, error code: 0x%x\n", error);
00234                 Close();
00235                 return false;
00236         }
00237         
00238         error = listen(m_socket, 5);
00239         if (error!=VCRT_OK)
00240         {
00241                 printf("\nsocket listen failed, error code: 0x%x\n", error);
00242                 Close();
00243                 return false;
00244         }
00245         m_bListening = true;
00246 
00247 #else
00248         m_socket = socket(AF_INET, SOCK_STREAM, 0);
00249         if (m_socket < 0) 
00250         {
00251                 m_socket = -1;
00252                 return false;
00253         }
00254         
00255         // set linger on - helps in closing socket immidiately
00256         linger li;
00257         li.l_onoff = true;
00258         li.l_linger = 0;
00259         
00260         if(setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &li, sizeof(li)) == -1)
00261         {
00262                 printf("setting linger option failed\n");
00263                 Close();
00264                 return false;
00265         }
00266         
00267         // set non blocking
00268         if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1)
00269         {
00270                 printf("setting non-blocking option failed\n");
00271                 Close();
00272                 return false;
00273         }
00274         
00275         struct sockaddr_in serv_addr;
00276         bzero((char *)&serv_addr, sizeof(serv_addr));
00277         
00278         serv_addr.sin_family = AF_INET;
00279         if (ip != NULL)
00280         {
00281                 bcopy(ip, (char *)&serv_addr.sin_addr.s_addr, 4);
00282         }
00283         else
00284         {
00285                 serv_addr.sin_addr.s_addr = INADDR_ANY;
00286         }
00287         serv_addr.sin_port = htons(port);
00288         
00289         if (bind(m_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
00290         {
00291                 Close();
00292                 return false;
00293         }
00294         
00295         listen(m_socket, 5);
00296         m_bListening = true;
00297 #endif
00298         
00299         return true;
00300 }
00301 
00302 CTCPSocket* CTCPSocket::Accept(unsigned char *ip)
00303 {
00304         if (m_socket == -1 || !m_bListening)
00305                 return NULL;
00306                 
00307 #ifdef WIN32
00308         SOCKET sock = (SOCKET)m_socket;
00309         struct sockaddr_in cli_addr;
00310         int clilen = sizeof(cli_addr);
00311 
00312         SOCKET new_socket = accept(sock, (struct sockaddr *) &cli_addr, &clilen);
00313         if (new_socket == INVALID_SOCKET)
00314         {
00315                 return NULL;
00316         }
00317 
00318         // set non blocking
00319         u_long v = 1;
00320         if (ioctlsocket(new_socket, FIONBIO, &v) == SOCKET_ERROR)
00321         {
00322                 printf("setting non-blocking option failed\n");
00323                 Close();
00324                 return false;
00325         }
00326         
00327         // set no delay for sending
00328         int v2 = 1;
00329         if (setsockopt(new_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&v2, sizeof(v2)) == -1)
00330         {
00331                 printf("newly accepted socket couldn't be set to no delay mode\n");
00332         }
00333 
00334         if (ip != NULL)
00335         {
00336                 memcpy(ip, (char *) &cli_addr.sin_addr.s_addr, 4);
00337         }
00338         
00339         CTCPSocket *s = new CTCPSocket();
00340         s->m_socket = (int) new_socket;
00341 
00342         return s;
00343 
00344 #elif defined(__TI_COMPILER_VERSION__)
00345         uint_32 error;
00346         
00347         // acccept is always blocking on vcrt, so we need to test for activity first
00348         // which is not blocking
00349         error = VCRT_selectset(&m_socket, 1, (uint_32)-1);
00350         
00351         if (error==0) //no new connections, nothing to do
00352         {
00353                 return NULL;
00354         }
00355         if (error==VCRT_SOCKET_ERROR) //an error occured
00356         {
00357                 printf("Error in accept(): VCRT_selectset failed, error code 0x%x\n", VCRT_geterror(m_socket));
00358                 return NULL;    
00359         }
00360         if (error!=m_socket) //should never happen as we check only this socket.
00361         {
00362                 printf("Error in accept(): VCRT_selectset returned invalid socket");
00363                 return NULL;    
00364         }
00365         
00366 
00367         sockaddr_in cli_addr;
00368         uint_16 clilen = sizeof(cli_addr);
00369         
00370         int new_socket = accept(m_socket, &cli_addr, &clilen);
00371         if (new_socket == VCRT_SOCKET_ERROR)
00372         {
00373                 error = VCRT_geterror(m_socket);
00374                 if (error == VCRT_OK)
00375                 {
00376                         printf("\nAccept: Connection reset by peer");
00377                 }
00378                 else
00379                 {
00380                         printf("Error, accept() failed with error code 0x%x\n", error);
00381                 }
00382                 return NULL;
00383         }
00384         
00385         
00386         
00387         // set non blocking
00388 
00389         // there is no socket-global (non-)blocking flag on VCRT
00390         // - accept() is always blocking and therefore guarded by VCRT_selectset().
00391         // - recv() behavior is set during Recv() depending on bWait flag
00392         // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms
00393         uint_32 opt_value;
00394         
00395         opt_value = TRUE;
00396         error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value));
00397         if (error != VCRT_OK)
00398         {
00399                 printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error);
00400         }
00401         
00402         
00403         
00404         // set no delay for sending
00405         // OPT_NO_NAGLE_ALGORITHM is the VCRT equivalent to TCP_NODELAY
00406         opt_value = TRUE;
00407         error = setsockopt(m_socket, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &opt_value, sizeof(opt_value));
00408         if (error != VCRT_OK)
00409         {
00410                 printf("Error, setsockopt(OPT_NO_NAGLE_ALGORITHM) failed with error code 0x%x\n", error);
00411         }
00412         
00413         
00414         
00415         if (ip != NULL)
00416         {
00417                 // vcrt expects inverse order of ip chars
00418                 // than provided by RemoteApplicationHandler.cpp
00419                 cli_addr.sin_addr.s_addr = revert_byte_order(cli_addr.sin_addr.s_addr);
00420                 //never cast ip to an int pointer! this would imply 4byte alignment.
00421                 memcpy( ip, &cli_addr.sin_addr.s_addr, 4);
00422         }
00423         
00424         CTCPSocket *sock = new CTCPSocket();
00425         sock->m_socket = new_socket;
00426         
00427         return sock;
00428 
00429 #else
00430         struct sockaddr_in cli_addr;
00431         socklen_t clilen = sizeof(cli_addr);
00432         
00433         int new_socket = accept(m_socket, (struct sockaddr *) &cli_addr, &clilen);
00434         if (new_socket < 0)
00435         {
00436                 return NULL;
00437         }
00438         
00439         // set non blocking
00440         if (fcntl(new_socket, F_SETFL, O_NONBLOCK) == -1)
00441         {
00442                 printf("newly accepted socket couldn't be set to non blocking mode\n");
00443         }
00444         
00445         // set no delay for sending
00446         int v = 1;
00447         if (setsockopt(new_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)) == -1)
00448         {
00449                 printf("newly accepted socket couldn't be set to no delay mode\n");
00450         } 
00451         
00452         if (ip != NULL)
00453         {
00454                 bcopy((char *)&cli_addr.sin_addr.s_addr, ip, 4);
00455         }
00456         
00457         CTCPSocket *sock = new CTCPSocket();
00458         sock->m_socket = new_socket;
00459         
00460         return sock;
00461 #endif
00462 }
00463 
00464 bool CTCPSocket::Open(const unsigned char *ip, int port)
00465 {
00466         Close();
00467         
00468 #ifdef WIN32
00469         SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
00470         if (sock == INVALID_SOCKET)
00471         {
00472                 m_socket = -1;
00473                 return false;
00474         }
00475 
00476         m_socket = (int)sock;
00477 
00478         struct sockaddr_in serv_addr;
00479         memset((char *)&serv_addr, 0, sizeof(serv_addr));
00480         
00481         serv_addr.sin_family = AF_INET;
00482         memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4);
00483         serv_addr.sin_port = htons(port);
00484         
00485         if (connect(sock, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
00486         {
00487                 Close();
00488                 return false;
00489         }
00490         
00491         // set non blocking (after connect)
00492         u_long v = 1;
00493         if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR)
00494         {
00495                 printf("setting non-blocking option failed\n");
00496                 Close();
00497                 return false;
00498         }
00499         
00500         // set no delay for sending
00501         int v2 = 1;
00502         if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&v2, sizeof(v2)) == -1)
00503         {
00504                 printf("socket couldn't be set to no delay mode\n");
00505         }
00506 
00507         m_bListening = false; 
00508 
00509 #elif defined(__TI_COMPILER_VERSION__)
00510         uint_32 error;
00511 
00512         m_socket = socket_stream();
00513         if (m_socket == VCRT_SOCKET_ERROR) 
00514         {
00515                 printf("Error in Open(): socket_stream() failed\n");
00516                 m_socket = -1;
00517                 return false;
00518         }
00519         
00520         sockaddr_in serv_addr;
00521         memset( &serv_addr, 0, sizeof(serv_addr));
00522         serv_addr.sin_family      = AF_INET;
00523         
00524         //never cast ip to an int pointer! this would imply 4byte alignment.
00525         memcpy(&(serv_addr.sin_addr.s_addr), ip, 4);
00526         // vcrt expects inverse order of ip chars
00527         // than provided by RemoteApplicationHandler.cpp
00528         serv_addr.sin_addr.s_addr = revert_byte_order(serv_addr.sin_addr.s_addr);
00529         
00530         serv_addr.sin_port = port; //htons(port); VCRT does not want the port in network byte order
00531 
00532         //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);
00533         
00534         error = connect(m_socket, &serv_addr, sizeof(serv_addr));
00535         if (error != VCRT_OK)
00536         {
00537                 printf("Error in Open(): connect failed, error code 0x%x\n", error);
00538                 Close();
00539                 return false;
00540         }
00541 
00542         // set non blocking (after connect)
00543 
00544         // there is no socket-global (non-)blocking flag on VCRT
00545         // - accept() is always blocking and therefore guarded by VCRT_selectset().
00546         // - recv() behavior is set during Recv() depending on bWait flag
00547         // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms
00548         uint_32 opt_value;
00549         
00550         opt_value = TRUE;
00551         error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value));
00552         if (error != VCRT_OK)
00553         {
00554                 printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error);
00555                 Close();
00556                 return false;
00557         }
00558 
00559         
00560         // set no delay for sending
00561         // OPT_NO_NAGLE_ALGORITHM is the VCRT equivalent to TCP_NODELAY
00562         opt_value = TRUE;
00563         error = setsockopt(m_socket, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &opt_value, sizeof(opt_value));
00564         if (error != VCRT_OK)
00565         {
00566                 printf("Error, setsockopt(OPT_NO_NAGLE_ALGORITHM) failed with error code 0x%x\n", error);
00567                 Close();
00568                 return false;
00569         }
00570         
00571         m_bListening = false;
00572 
00573 #else
00574         m_socket = socket(AF_INET, SOCK_STREAM, 0);
00575         if (m_socket < 0) 
00576         {
00577                 m_socket = -1;
00578                 return false;
00579         }
00580         
00581         struct sockaddr_in serv_addr;
00582         bzero((char *)&serv_addr, sizeof(serv_addr));
00583         
00584         serv_addr.sin_family = AF_INET;
00585         bcopy(ip, (char *)&serv_addr.sin_addr.s_addr, 4);
00586         serv_addr.sin_port = htons(port);
00587         
00588         if (connect(m_socket, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
00589         {
00590                 Close();
00591                 return false;
00592         }
00593         
00594         // set non blocking (after connect)
00595         if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1)
00596         {
00597                 Close();
00598                 return false;
00599         }
00600         
00601         // set no delay for sending
00602         int v = 1;
00603         if (setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)) == -1)
00604         {
00605                 Close();
00606                 return false;
00607         } 
00608         
00609         m_bListening = false;
00610 #endif
00611         
00612         return true;
00613 }
00614 
00615 void CTCPSocket::Close()
00616 {
00617         if (m_socket == -1)
00618                 return;
00619                 
00620 #ifdef WIN32
00621         SOCKET sock = (SOCKET)m_socket;
00622         closesocket(sock);
00623 
00624 #elif defined(__TI_COMPILER_VERSION__)
00625         // FLAG_ABORT_CONNECTION enforces hard closing of the socket as specified
00626         // by the SO_LINGER socket option with zero timeout on other platforms.
00627         // SO_LINGER is not available on VCRT.
00628         uint_32 error = shutdown(m_socket, FLAG_ABORT_CONNECTION);
00629         if(error!= VCRT_OK)
00630         {
00631                 printf("\nsocket shutdown failed, error code: 0x%x\n", error);
00632         }
00633 #else
00634         close(m_socket);
00635 #endif
00636 
00637         m_socket = -1;
00638 }
00639 
00640 bool CTCPSocket::Send(const void *pData, int nBytes)
00641 {
00642         if (m_socket == -1 || m_bListening)
00643                 return false;
00644         
00645 #ifdef WIN32
00646         SOCKET sock = (SOCKET)m_socket;
00647         int size = 0;
00648         unsigned char *ptr = (unsigned char*) pData;
00649         while (true)
00650         {
00651                 int s = send(sock, (const char *) ptr, nBytes, 0);
00652                 if (s == SOCKET_ERROR)
00653                 {
00654                         int errnum = WSAGetLastError();
00655                         if (errnum == WSAEWOULDBLOCK)
00656                                 continue;
00657                         
00658                         return false;
00659                 }
00660                 
00661                 size += s;
00662                 ptr += s;
00663                 nBytes -= s;
00664                 if (nBytes == 0)
00665                         break;
00666                 
00667         }
00668 
00669 #elif defined(__TI_COMPILER_VERSION__)
00670         
00671         char *ptr = (char *) pData;
00672         while (nBytes>0)
00673         {
00674                 // as OPT_SEND_NOWAIT is set above, this blocks until data is buffered
00675                 // but does not wait for data to be send and acknowledged.
00676                 // Send() therefore blocks until all data is passed on to the OS.
00677                 int_32 count = send(m_socket, ptr, nBytes, 0);
00678 
00679                 if (count==VCRT_ERROR)
00680                 {
00681                         printf("Error in Send(): send failed, error code 0x%x\n", VCRT_geterror(m_socket));
00682                         return false;
00683                 }
00684                 
00685                 ptr += count;
00686                 nBytes -= count;
00687         }
00688 
00689 #else
00690         int size = 0;
00691         unsigned char *ptr = (unsigned char *) pData;
00692         while (true)
00693         {
00694                 int s = write(m_socket, ptr, nBytes);
00695                 if (s == -1)
00696                 {
00697                         int errnum = errno;
00698                         if (errnum == EAGAIN)
00699                                 continue;
00700                         
00701                         return false;
00702                 }
00703                 
00704                 size += s;
00705                 ptr += s;
00706                 nBytes -= s;
00707                 if (nBytes == 0)
00708                         break;
00709                 
00710         }
00711 #endif
00712         
00713         return true;
00714 }
00715 
00716 int CTCPSocket::Recv(void *pData, int nMaxBytes, bool bWait)
00717 {
00718         if (m_socket == -1 || m_bListening)
00719                 return -1;
00720         
00721 #ifdef WIN32
00722         SOCKET sock = (SOCKET) m_socket;
00723 
00724         if (bWait)
00725         {
00726                 int size = 0;
00727                 unsigned char *ptr = (unsigned char*) pData;
00728                 while (true)
00729                 {
00730                         int s = recv(sock, (char *) ptr, nMaxBytes, 0);
00731                         if (s == SOCKET_ERROR)
00732                         {
00733                                 int errnum = WSAGetLastError();
00734                                 if (errnum == WSAEWOULDBLOCK)
00735                                         continue;
00736                         
00737                                 // this is really bad, the connection is probably dead
00738                                 return -1;
00739                         }
00740                         
00741                         ptr += s;
00742                         size += s;
00743                         nMaxBytes -= s; 
00744                         
00745                         if (nMaxBytes == 0)
00746                                 return size;
00747                                 
00748                 }
00749         }
00750         else
00751         {
00752                 int size = recv(sock, (char *) pData, nMaxBytes, 0);
00753                 if (size == SOCKET_ERROR)
00754                 {
00755                         int errnum = WSAGetLastError();
00756                         if (errnum == WSAEWOULDBLOCK)
00757                                 return 0;
00758                         
00759                         // this is really bad, the connection is probably dead
00760                 
00761                         return -1;
00762                 }
00763                 else if (size == 0)
00764                 {
00765                         return -1;
00766                 }
00767                 
00768                 return size;
00769         }
00770 
00771 #elif defined(__TI_COMPILER_VERSION__)
00772         //set OPT_RECV_NOWAIT depending on bWait
00773         // if bWait==false: behaves like a non-blocking socket on other platforms
00774         // else: recv() blocks, avoiding polling with busy waiting.
00775         //       recv() may non the less return early in case of a PUSH flag.
00776         uint_32 opt_value = bWait? FALSE : TRUE;
00777         uint_32 error = setsockopt(m_socket, SOL_TCP, OPT_RECEIVE_NOWAIT, &opt_value, sizeof(opt_value));
00778         if (error != VCRT_OK)
00779         {
00780                 printf("Error in Recv(), setsockopt(OPT_RECEIVE_NOWAIT) failed with error code 0x%x\n", error);
00781                 return -1;
00782         }
00783 
00784         if (bWait)
00785         {
00786                 int size = 0;
00787                 char *ptr = (char *) pData;
00788                 while (nMaxBytes>0)
00789                 {
00790                         int_32 count = recv(m_socket, ptr, nMaxBytes, 0); //is set to blocking above
00791                         
00792                         if (count == VCRT_ERROR)
00793                         {
00794                                 printf("Error in Recv(): recv failed, error code 0x%x\n", VCRT_geterror(m_socket));
00795                                 // this is really bad, the connection is probably dead
00796                                 return -1;
00797                         }
00798                         
00799                         ptr += count;
00800                         size += count;
00801                         nMaxBytes -= count; 
00802                 }
00803                 return size;
00804         }
00805         else
00806         {
00807                 //receive whatever data is available and return immediately
00808                 int_32 count = recv(m_socket, (char*)pData, nMaxBytes, 0); //is set to non-blocking above
00809 
00810                 if (count == VCRT_ERROR)
00811                 {
00812                         printf("Error in Recv(): recv failed, error code 0x%x\n", VCRT_geterror(m_socket));
00813                         // this is really bad, the connection is probably dead
00814                         return -1;
00815                 }
00816                 // on vcrt, count==0 means zero bytes received and not connection closed by peer.
00817                 // so in this case 0 is returned and not -1.
00818                 
00819                 return count;
00820         }
00821 
00822 #else
00823         if (bWait)
00824         {
00825                 int size = 0;
00826                 unsigned char *ptr = (unsigned char *) pData;
00827                 while (true)
00828                 {
00829                         int s = (int) recv(m_socket, ptr, nMaxBytes, 0);
00830                         if (s == -1)
00831                         {
00832                                 int errnum = errno;
00833                                 if (errnum == EAGAIN)
00834                                         continue;
00835                         
00836                                 // this is really bad, the connection is probably dead
00837                 
00838                                 return -1;
00839                         }
00840                         
00841                         ptr += s;
00842                         size += s;
00843                         nMaxBytes -= s; 
00844                         
00845                         if (nMaxBytes == 0)
00846                                 return size;
00847                                 
00848                 }
00849         }
00850         else
00851         {
00852                 int size = (int) recv(m_socket, pData, nMaxBytes, 0);
00853                 if (size == -1)
00854                 {
00855                         int errnum = errno;
00856                         if (errnum == EAGAIN)
00857                                 return 0;
00858                         
00859                         // this is really bad, the connection is probably dead
00860                 
00861                         return -1;
00862                 }
00863                 else if (size == 0)
00864                 {
00865                         return -1;
00866                 }
00867                 
00868                 return size;
00869         }
00870 #endif
00871         
00872         return -1;
00873 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:58