Changeset 15 in flair-src for trunk/lib/FlairCore/src/TcpSocket.cpp


Ignore:
Timestamp:
Apr 8, 2016, 3:40:57 PM (6 years ago)
Author:
Bayard Gildas
Message:

sources reformatted with flair-format-dir script

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/FlairCore/src/TcpSocket.cpp

    r2 r15  
    2828namespace core {
    2929
    30 TcpSocket::TcpSocket(const Object* parent,const std::string name,bool _blockOnSend,bool _blockOnReceive):ConnectedSocket(parent,name),isConnected(false) {
    31     blockOnSend=_blockOnSend;
    32     blockOnReceive=_blockOnReceive;
     30TcpSocket::TcpSocket(const Object *parent, const std::string name,
     31                     bool _blockOnSend, bool _blockOnReceive)
     32    : ConnectedSocket(parent, name), isConnected(false) {
     33  blockOnSend = _blockOnSend;
     34  blockOnReceive = _blockOnReceive;
    3335}
    3436
    3537TcpSocket::~TcpSocket() {
    36     //Info("Debug: destroying TCP socket %s", ObjectName().c_str());
     38  // Info("Debug: destroying TCP socket %s", ObjectName().c_str());
     39  close(socket);
     40}
     41
     42void TcpSocket::Listen(const unsigned int port,
     43                       const std::string localAddress) {
     44  socket = ::socket(AF_INET, SOCK_STREAM, 0);
     45
     46  sockaddr_in my_addr;
     47  my_addr.sin_family = AF_INET;
     48  my_addr.sin_port = htons(port);
     49  if (localAddress == "ANY") {
     50    my_addr.sin_addr.s_addr = INADDR_ANY;
     51  } else {
     52    inet_aton(localAddress.c_str(), &(my_addr.sin_addr));
     53  }
     54  memset(&(my_addr.sin_zero), '\0', 8);
     55
     56  if (bind(socket, (sockaddr *)&my_addr, sizeof(my_addr)) < 0) {
     57    char errorMsg[256];
     58    Err("TCP bind, %s\n", strerror_r(errno, errorMsg, sizeof(errorMsg)));
     59  }
     60
     61  listen(socket, 1);
     62}
     63
     64TcpSocket *TcpSocket::Accept(Time timeout) {
     65  char errorMsg[256];
     66  TcpSocket *acceptedSocket = nullptr;
     67
     68  struct timeval tv;
     69  if (timeout != 0) {
     70    tv.tv_sec = timeout / 1000; // timeout is in ms
     71    tv.tv_usec = (timeout % 1000) * 1000;
     72  }
     73  fd_set rset;
     74  FD_ZERO(&rset);
     75  FD_SET(socket, &rset);
     76  int ret = select(socket + 1, &rset, nullptr, nullptr,
     77                   (timeout == 0) ? nullptr : &tv); // man 2 accept
     78  if (ret < 0) {
     79    Err("select: %s\n", strerror_r(errno, errorMsg, sizeof(errorMsg)));
     80  } else {
     81    if (ret == 0) {
     82      // timeout reached
     83      // Err("timeout reached\n");
     84    } else {
     85      // our socket is readable, a new connection can be accepted
     86      acceptedSocket = new TcpSocket(this->Parent(), this->ObjectName(),
     87                                     blockOnSend, blockOnReceive);
     88      sockaddr_in their_addr;
     89      socklen_t namelen = sizeof(their_addr);
     90      if ((acceptedSocket->socket =
     91               accept(socket, (sockaddr *)&their_addr, &namelen)) < 0) {
     92        Err("error: %s\n", strerror_r(errno, errorMsg, sizeof(errorMsg)));
     93        delete acceptedSocket;
     94        acceptedSocket = nullptr;
     95      }
     96    }
     97  }
     98
     99  return acceptedSocket;
     100}
     101
     102bool TcpSocket::Connect(const unsigned int distantPort,
     103                        const std::string distantAddress, Time timeout) {
     104  bool success = false;
     105  char errorMsg[256];
     106
     107  if (isConnected) {
     108    if (this->distantPort == distantPort &&
     109        this->distantAddress == distantAddress) {
     110      return true;
     111    } else {
     112      close(socket);
     113    }
     114  }
     115  socket = ::socket(AF_INET, SOCK_STREAM, 0);
     116  if (socket == -1)
     117    return false;
     118
     119  sockaddr_in serv_addr;
     120  serv_addr.sin_family = AF_INET;
     121  serv_addr.sin_port = htons(short(distantPort));
     122  if (inet_pton(AF_INET, distantAddress.c_str(), &serv_addr.sin_addr) <= 0) {
     123    printf("incorrect network address.");
    37124    close(socket);
    38 }
    39 
    40 void TcpSocket::Listen(const unsigned int port,const std::string localAddress) {
    41     socket=::socket(AF_INET,SOCK_STREAM,0);
    42 
    43     sockaddr_in my_addr;
    44     my_addr.sin_family = AF_INET;
    45     my_addr.sin_port = htons(port);
    46     if (localAddress=="ANY") {
    47         my_addr.sin_addr.s_addr=INADDR_ANY;
     125    return false;
     126  }
     127  memset(&(serv_addr.sin_zero), '\0', 8);
     128
     129  // go non blocking
     130  int flags = fcntl(socket, F_GETFL);
     131  fcntl(socket, F_SETFL, flags | O_NONBLOCK);
     132  if (connect(socket, (sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
     133    if ((errno != EINPROGRESS) && (errno != EAGAIN)) {
     134      Err("socket connect: %s\n",
     135          strerror_r(errno, errorMsg, sizeof(errorMsg)));
     136      success = false;
    48137    } else {
    49         inet_aton(localAddress.c_str(),&(my_addr.sin_addr));
     138      // now block with a timeout
     139      struct timeval tv;
     140      if (timeout != 0) {
     141        tv.tv_sec = timeout / 1000; // timeout is in ms
     142        tv.tv_usec = (timeout % 1000) * 1000;
     143      }
     144      fd_set wset;
     145      FD_ZERO(&wset);
     146      FD_SET(socket, &wset);
     147      int ret =
     148          select(socket + 1, NULL, &wset, NULL,
     149                 (timeout == 0) ? NULL : &tv); // man 2 connect EINPROGRESS
     150      if (ret < 0) {
     151        Err("select: %s\n", strerror_r(errno, errorMsg, sizeof(errorMsg)));
     152        success = false;
     153      } else {
     154        if (ret == 0) {
     155          // timeout reached
     156          // Err("timeout reached\n");
     157          success = false;
     158        } else {
     159          // something happened on our socket. Check if an error occured
     160          int error;
     161          socklen_t len = sizeof(error);
     162          if (getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len) != 0) {
     163            // Err("getsockopt:
     164            // %s\n",strerror_r(errno,errorMsg,sizeof(errorMsg)));
     165            success = false;
     166          } else if (error != 0) {
     167            // Err("socket error:
     168            // %d(%s)\n",error,strerror_r(error,errorMsg,sizeof(errorMsg)));
     169            success = false;
     170          } else {
     171            if (connect(socket, (sockaddr *)&serv_addr, sizeof(serv_addr)) ==
     172                -1) {
     173              success = false;
     174            } else {
     175              // Info("connected indeed ^^\n");
     176              success = true;
     177            }
     178          }
     179        }
     180      }
    50181    }
    51     memset(&(my_addr.sin_zero), '\0', 8);
    52 
    53     if (bind(socket,(sockaddr*)&my_addr,sizeof(my_addr))<0) {
    54         char errorMsg[256];
    55         Err("TCP bind, %s\n",strerror_r(errno,errorMsg,sizeof(errorMsg)));
    56     }
    57 
    58     listen(socket,1);
    59 }
    60 
    61 TcpSocket *TcpSocket::Accept(Time timeout) {
    62     char errorMsg[256];
    63     TcpSocket *acceptedSocket=nullptr;
    64 
     182  } else {
     183    success = true; // never reached suprisingly...
     184  }
     185  // switch back to blocking mode (default)
     186  fcntl(socket, F_SETFL, flags);
     187
     188  if (!success) {
     189    close(socket);
     190    // Info("Debug: Connect to %s:%d failed\n", distantAddress.c_str(),
     191    // distantPort);
     192    return false;
     193  } else {
     194    isConnected = true;
     195    this->distantPort = distantPort;
     196    this->distantAddress = distantAddress;
     197    // Info("Debug: Connect to %s:%d succeeded\n", distantAddress.c_str(),
     198    // distantPort);
     199    return true;
     200  }
     201}
     202
     203ssize_t TcpSocket::SendMessage(const char *buffer, size_t bufferSize,
     204                               Time timeout) {
     205  int flags = 0;
     206  if (!blockOnSend) {
     207    flags |= MSG_DONTWAIT;
     208  } else {
    65209    struct timeval tv;
    66     if (timeout!=0) {
    67         tv.tv_sec=timeout/1000; //timeout is in ms
    68         tv.tv_usec=(timeout%1000)*1000;
    69     }
    70     fd_set rset;
    71     FD_ZERO(&rset);
    72     FD_SET(socket, &rset);
    73     int ret=select(socket + 1, &rset, nullptr, nullptr,(timeout==0)?nullptr:&tv); //man 2 accept
    74     if (ret<0) {
    75         Err("select: %s\n",strerror_r(errno,errorMsg,sizeof(errorMsg)));
    76     } else {
    77         if (ret==0) {
    78             //timeout reached
    79             //Err("timeout reached\n");
    80         } else {
    81             //our socket is readable, a new connection can be accepted
    82             acceptedSocket=new TcpSocket(this->Parent(),this->ObjectName(),blockOnSend,blockOnReceive);
    83             sockaddr_in their_addr;
    84             socklen_t namelen = sizeof(their_addr);
    85             if ((acceptedSocket->socket=accept(socket,(sockaddr*)&their_addr, &namelen))<0) {
    86                 Err("error: %s\n",strerror_r(errno,errorMsg,sizeof(errorMsg)));
    87                 delete acceptedSocket;
    88                 acceptedSocket=nullptr;
    89             }
    90         }
    91     }
    92 
    93     return acceptedSocket;
    94 }
    95 
    96 bool TcpSocket::Connect(const unsigned int distantPort,const std::string distantAddress,Time timeout) {
    97     bool success=false;
    98     char errorMsg[256];
    99 
    100     if (isConnected) {
    101         if (this->distantPort==distantPort && this->distantAddress==distantAddress) {
    102             return true;
    103         } else {
    104             close(socket);
    105         }
    106     }
    107     socket=::socket(AF_INET,SOCK_STREAM,0);
    108     if (socket==-1) return false;
    109 
    110     sockaddr_in serv_addr;
    111     serv_addr.sin_family = AF_INET;
    112     serv_addr.sin_port = htons(short(distantPort));
    113     if (inet_pton(AF_INET, distantAddress.c_str(), &serv_addr.sin_addr) <= 0) {
    114         printf("incorrect network address.");
    115         close(socket);
    116         return false;
    117     }
    118     memset(&(serv_addr.sin_zero), '\0', 8);
    119 
    120     //go non blocking
    121     int flags=fcntl(socket, F_GETFL);
    122     fcntl(socket, F_SETFL, flags | O_NONBLOCK);
    123     if (connect(socket, (sockaddr*)&serv_addr, sizeof(serv_addr))==-1) {
    124         if ((errno != EINPROGRESS) && (errno != EAGAIN)){
    125             Err("socket connect: %s\n",strerror_r(errno,errorMsg,sizeof(errorMsg)));
    126             success=false;
    127         } else {
    128             //now block with a timeout
    129             struct timeval tv;
    130             if (timeout!=0) {
    131                 tv.tv_sec=timeout/1000; //timeout is in ms
    132                 tv.tv_usec=(timeout%1000)*1000;
    133             }
    134             fd_set wset;
    135             FD_ZERO(&wset);
    136             FD_SET(socket, &wset);
    137             int ret=select(socket + 1, NULL, &wset, NULL,(timeout==0)?NULL:&tv); //man 2 connect EINPROGRESS
    138             if (ret<0) {
    139                 Err("select: %s\n",strerror_r(errno,errorMsg,sizeof(errorMsg)));
    140                 success=false;
    141             } else {
    142                 if (ret==0) {
    143                     //timeout reached
    144                     //Err("timeout reached\n");
    145                     success=false;
    146                 } else {
    147                     //something happened on our socket. Check if an error occured
    148                     int error;
    149                     socklen_t len = sizeof(error);
    150                     if (getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len)!=0) {
    151                         //Err("getsockopt: %s\n",strerror_r(errno,errorMsg,sizeof(errorMsg)));
    152                         success=false;
    153                     } else if (error!=0) {
    154                         //Err("socket error: %d(%s)\n",error,strerror_r(error,errorMsg,sizeof(errorMsg)));
    155                         success=false;
    156                     } else {
    157                         if (connect(socket, (sockaddr*)&serv_addr, sizeof(serv_addr))==-1) {
    158                             success=false;
    159                         } else {
    160                             //Info("connected indeed ^^\n");
    161                             success=true;
    162                         }
    163                     }
    164                 }
    165             }
    166         }
    167     } else {
    168         success=true; //never reached suprisingly...
    169     }
    170     //switch back to blocking mode (default)
    171     fcntl(socket, F_SETFL, flags);
    172 
    173     if (!success) {
    174         close(socket);
    175         //Info("Debug: Connect to %s:%d failed\n", distantAddress.c_str(), distantPort);
    176         return false;
    177     } else {
    178         isConnected=true;
    179         this->distantPort=distantPort;
    180         this->distantAddress=distantAddress;
    181         //Info("Debug: Connect to %s:%d succeeded\n", distantAddress.c_str(), distantPort);
    182         return true;
    183     }
    184 }
    185 
    186 ssize_t TcpSocket::SendMessage(const char* buffer,size_t bufferSize,Time timeout){
    187     int flags=0;
    188     if (!blockOnSend) {
    189         flags|=MSG_DONTWAIT;
    190     } else {
    191         struct timeval tv;
    192         tv.tv_sec=timeout/1000; //timeout is in ms
    193         tv.tv_usec=(timeout%1000)*1000;
    194 
    195         setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&tv,sizeof(struct timeval));
    196     }
    197     ssize_t bytesSent=send(socket, buffer, bufferSize, flags);
    198 
    199     return bytesSent;
    200 }
    201 
    202 ssize_t TcpSocket::RecvMessage(char* buffer,size_t bufferSize,Time timeout){
    203     int flags=0;
    204     if (!blockOnReceive) {
    205         flags|=MSG_DONTWAIT;
    206     } else {
    207         struct timeval tv;
    208         tv.tv_sec=timeout/1000; //timeout is in ms
    209         tv.tv_usec=(timeout%1000)*1000;
    210 
    211         setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&tv,sizeof(struct timeval));
    212     }
    213     ssize_t bytesRead=recv(socket,buffer,bufferSize,flags);
    214 
    215     return bytesRead;
    216 }
    217 
    218 uint16_t TcpSocket::NetworkToHost16(uint16_t data) {
    219     return ntohs(data);
    220 }
    221 
    222 uint16_t TcpSocket::HostToNetwork16(uint16_t data) {
    223     return htons(data);
    224 }
    225 
    226 uint32_t TcpSocket::NetworkToHost32(uint32_t data) {
    227     return ntohl(data);
    228 }
    229 
    230 uint32_t TcpSocket::HostToNetwork32(uint32_t data) {
    231     return htonl(data);
    232 }
     210    tv.tv_sec = timeout / 1000; // timeout is in ms
     211    tv.tv_usec = (timeout % 1000) * 1000;
     212
     213    setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv,
     214               sizeof(struct timeval));
     215  }
     216  ssize_t bytesSent = send(socket, buffer, bufferSize, flags);
     217
     218  return bytesSent;
     219}
     220
     221ssize_t TcpSocket::RecvMessage(char *buffer, size_t bufferSize, Time timeout) {
     222  int flags = 0;
     223  if (!blockOnReceive) {
     224    flags |= MSG_DONTWAIT;
     225  } else {
     226    struct timeval tv;
     227    tv.tv_sec = timeout / 1000; // timeout is in ms
     228    tv.tv_usec = (timeout % 1000) * 1000;
     229
     230    setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,
     231               sizeof(struct timeval));
     232  }
     233  ssize_t bytesRead = recv(socket, buffer, bufferSize, flags);
     234
     235  return bytesRead;
     236}
     237
     238uint16_t TcpSocket::NetworkToHost16(uint16_t data) { return ntohs(data); }
     239
     240uint16_t TcpSocket::HostToNetwork16(uint16_t data) { return htons(data); }
     241
     242uint32_t TcpSocket::NetworkToHost32(uint32_t data) { return ntohl(data); }
     243
     244uint32_t TcpSocket::HostToNetwork32(uint32_t data) { return htonl(data); }
    233245
    234246} // end namespace core
Note: See TracChangeset for help on using the changeset viewer.