drivers/can_tcp_win32/Socket.cpp
changeset 355 12adbd08e10c
equal deleted inserted replaced
354:396ac66670ad 355:12adbd08e10c
       
     1 /* 
       
     2    Socket.cpp
       
     3 
       
     4    Copyright (C) 2002-2004 René Nyffenegger
       
     5 
       
     6    This source code is provided 'as-is', without any express or implied
       
     7    warranty. In no event will the author be held liable for any damages
       
     8    arising from the use of this software.
       
     9 
       
    10    Permission is granted to anyone to use this software for any purpose,
       
    11    including commercial applications, and to alter it and redistribute it
       
    12    freely, subject to the following restrictions:
       
    13 
       
    14    1. The origin of this source code must not be misrepresented; you must not
       
    15       claim that you wrote the original source code. If you use this source code
       
    16       in a product, an acknowledgment in the product documentation would be
       
    17       appreciated but is not required.
       
    18 
       
    19    2. Altered source versions must be plainly marked as such, and must not be
       
    20       misrepresented as being the original source code.
       
    21 
       
    22    3. This notice may not be removed or altered from any source distribution.
       
    23 
       
    24    René Nyffenegger rene.nyffenegger@adp-gmbh.ch
       
    25 */
       
    26 
       
    27 
       
    28 #include "Socket.h"
       
    29 #include <iostream>
       
    30 
       
    31 using namespace std;
       
    32 
       
    33 int Socket::nofSockets_= 0;
       
    34 
       
    35 void Socket::Start() {
       
    36   if (!nofSockets_) {
       
    37     WSADATA info;
       
    38     if (WSAStartup(MAKEWORD(2,0), &info)) {
       
    39       throw "Could not start WSA";
       
    40     }
       
    41   }
       
    42   ++nofSockets_;
       
    43 }
       
    44 
       
    45 void Socket::End() {
       
    46   WSACleanup();
       
    47 }
       
    48 
       
    49 Socket::Socket() : s_(0) {
       
    50   Start();
       
    51   // UDP: use SOCK_DGRAM instead of SOCK_STREAM
       
    52   s_ = socket(AF_INET,SOCK_STREAM,0);
       
    53 
       
    54   if (s_ == INVALID_SOCKET) {
       
    55     throw "INVALID_SOCKET";
       
    56   }
       
    57 
       
    58   refCounter_ = new int(1);
       
    59 }
       
    60 
       
    61 Socket::Socket(SOCKET s) : s_(s) {
       
    62   Start();
       
    63   refCounter_ = new int(1);
       
    64 };
       
    65 
       
    66 Socket::~Socket() {
       
    67   if (! --(*refCounter_)) {
       
    68     Close();
       
    69     delete refCounter_;
       
    70   }
       
    71 
       
    72   --nofSockets_;
       
    73   if (!nofSockets_) End();
       
    74 }
       
    75 
       
    76 Socket::Socket(const Socket& o) {
       
    77   refCounter_=o.refCounter_;
       
    78   (*refCounter_)++;
       
    79   s_         =o.s_;
       
    80 
       
    81   nofSockets_++;
       
    82 }
       
    83 
       
    84 Socket& Socket::operator=(Socket& o) {
       
    85   (*o.refCounter_)++;
       
    86 
       
    87   refCounter_=o.refCounter_;
       
    88   s_         =o.s_;
       
    89 
       
    90   nofSockets_++;
       
    91 
       
    92   return *this;
       
    93 }
       
    94 
       
    95 void Socket::Close() {
       
    96   closesocket(s_);
       
    97 }
       
    98 
       
    99 std::string Socket::ReceiveBytes() {
       
   100   std::string ret;
       
   101   char buf[1024];
       
   102  
       
   103   while (1) {
       
   104     u_long arg = 0;
       
   105     if (ioctlsocket(s_, FIONREAD, &arg) != 0)
       
   106       break;
       
   107 
       
   108     if (arg == 0)
       
   109       break;
       
   110 
       
   111     if (arg > 1024) arg = 1024;
       
   112 
       
   113     int rv = recv (s_, buf, arg, 0);
       
   114     if (rv <= 0) break;
       
   115 
       
   116     std::string t;
       
   117 
       
   118     t.assign (buf, rv);
       
   119     ret += t;
       
   120   }
       
   121  
       
   122   return ret;
       
   123 }
       
   124 
       
   125 std::string Socket::ReceiveLine() {
       
   126   std::string ret;
       
   127   while (1) {
       
   128     char r;
       
   129 
       
   130     switch(recv(s_, &r, 1, 0)) {
       
   131       case 0: // not connected anymore;
       
   132               // ... but last line sent
       
   133               // might not end in \n,
       
   134               // so return ret anyway.
       
   135         return ret;
       
   136       case -1:
       
   137         return "";
       
   138 //      if (errno == EAGAIN) {
       
   139 //        return ret;
       
   140 //      } else {
       
   141 //      // not connected anymore
       
   142 //      return "";
       
   143 //      }
       
   144     }
       
   145 
       
   146     if (r == '\n')  return ret;
       
   147     ret += r;
       
   148   }
       
   149 }
       
   150 
       
   151 void Socket::SendLine(std::string s) {
       
   152   s += '\n';
       
   153   send(s_,s.c_str(),s.length(),0);
       
   154 }
       
   155 
       
   156 void Socket::SendBytes(const std::string& s) {
       
   157   send(s_,s.c_str(),s.length(),0);
       
   158 }
       
   159 
       
   160 SocketServer::SocketServer(int port, int connections, TypeSocket type) {
       
   161   sockaddr_in sa;
       
   162 
       
   163   memset(&sa, 0, sizeof(sa));
       
   164 
       
   165   sa.sin_family = PF_INET;             
       
   166   sa.sin_port = htons(port);          
       
   167   s_ = socket(AF_INET, SOCK_STREAM, 0);
       
   168   if (s_ == INVALID_SOCKET) {
       
   169     throw "INVALID_SOCKET";
       
   170   }
       
   171 
       
   172   if(type==NonBlockingSocket) {
       
   173     u_long arg = 1;
       
   174     ioctlsocket(s_, FIONBIO, &arg);
       
   175   }
       
   176 
       
   177   /* bind the socket to the internet address */
       
   178   if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) {
       
   179     closesocket(s_);
       
   180     throw "INVALID_SOCKET";
       
   181   }
       
   182   
       
   183   listen(s_, connections);                               
       
   184 }
       
   185 
       
   186 Socket* SocketServer::Accept() {
       
   187   SOCKET new_sock = accept(s_, 0, 0);
       
   188   if (new_sock == INVALID_SOCKET) {
       
   189     int rc = WSAGetLastError();
       
   190     if(rc==WSAEWOULDBLOCK) {
       
   191       return 0; // non-blocking call, no request pending
       
   192     }
       
   193     else {
       
   194       throw "Invalid Socket";
       
   195     }
       
   196   }
       
   197 
       
   198   Socket* r = new Socket(new_sock);
       
   199   return r;
       
   200 }
       
   201 
       
   202 SocketClient::SocketClient(const std::string& host, int port) : Socket() {
       
   203   std::string error;
       
   204 
       
   205   hostent *he;
       
   206   if ((he = gethostbyname(host.c_str())) == 0) {
       
   207     error = strerror(errno);
       
   208     throw error;
       
   209   }
       
   210 
       
   211   sockaddr_in addr;
       
   212   addr.sin_family = AF_INET;
       
   213   addr.sin_port = htons(port);
       
   214   addr.sin_addr = *((in_addr *)he->h_addr);
       
   215   memset(&(addr.sin_zero), 0, 8); 
       
   216 
       
   217   if (::connect(s_, (sockaddr *) &addr, sizeof(sockaddr))) {
       
   218     error = strerror(WSAGetLastError());
       
   219     throw error;
       
   220   }
       
   221 }
       
   222 
       
   223 SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) {
       
   224   FD_ZERO(&fds_);
       
   225   FD_SET(const_cast<Socket*>(s1)->s_,&fds_);
       
   226   if(s2) {
       
   227     FD_SET(const_cast<Socket*>(s2)->s_,&fds_);
       
   228   }     
       
   229 
       
   230   TIMEVAL tval;
       
   231   tval.tv_sec  = 0;
       
   232   tval.tv_usec = 1;
       
   233 
       
   234   TIMEVAL *ptval;
       
   235   if(type==NonBlockingSocket) {
       
   236     ptval = &tval;
       
   237   }
       
   238   else { 
       
   239     ptval = 0;
       
   240   }
       
   241 
       
   242   if (select (0, &fds_, (fd_set*) 0, (fd_set*) 0, ptval) == SOCKET_ERROR) 
       
   243     throw "Error in select";
       
   244 }
       
   245 
       
   246 bool SocketSelect::Readable(Socket const* const s) {
       
   247   if (FD_ISSET(s->s_,&fds_)) return true;
       
   248   return false;
       
   249 }