source: flair-src/trunk/lib/FlairCore/src/UdtSocket.cpp @ 67

Last change on this file since 67 was 15, checked in by Bayard Gildas, 6 years ago

sources reformatted with flair-format-dir script

File size: 4.6 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5//  created:    2015/04/21
6//  filename:   UdtSocket.cpp
7//
8//  author:     Gildas Bayard
9//              Copyright Heudiasyc UMR UTC/CNRS 7253
10//
11//  version:    $Id: $
12//
13//  purpose:    Class defining a UDT socket
14//
15//
16/*********************************************************************/
17#include "UdtSocket.h"
18#include <udt.h>
19#include <sys/socket.h>
20#include <netinet/in.h>
21#include <arpa/inet.h>
22#include <string.h>
23
24using std::string;
25
26namespace flair {
27namespace core {
28
29UdtSocket::UdtSocket(const Object *parent, const std::string name,
30                     bool _blockOnSend, bool _blockOnReceive)
31    : ConnectedSocket(parent, name) {
32  UDT::startup();
33  blockOnSend = _blockOnSend;
34  blockOnReceive = _blockOnReceive;
35}
36
37UdtSocket::~UdtSocket() {}
38
39void UdtSocket::Listen(const unsigned int port,
40                       const std::string localAddress) {
41  socket = UDT::socket(AF_INET, SOCK_DGRAM, 0);
42
43  UDT::setsockopt(socket, 0, UDT_SNDSYN, &blockOnSend, sizeof(bool));
44  UDT::setsockopt(socket, 0, UDT_RCVSYN, &blockOnReceive, sizeof(bool));
45  bool reuse = true;
46  UDT::setsockopt(socket, 0, UDT_REUSEADDR, &reuse, sizeof(bool));
47
48  sockaddr_in my_addr;
49  my_addr.sin_family = AF_INET;
50  my_addr.sin_port = htons(port);
51  if (localAddress == "ANY") {
52    my_addr.sin_addr.s_addr = INADDR_ANY;
53  } else {
54    inet_aton(localAddress.c_str(), &(my_addr.sin_addr));
55  }
56  memset(&(my_addr.sin_zero), '\0', 8);
57
58  if (UDT::ERROR == UDT::bind(socket, (sockaddr *)&my_addr, sizeof(my_addr))) {
59    Err("bind, %s\n", UDT::getlasterror().getErrorMessage());
60  }
61
62  UDT::listen(socket, 1);
63}
64
65UdtSocket *UdtSocket::Accept(Time timeout) {
66  // TIMEOUT UNSUPPORTED!!
67  UdtSocket *acceptedSocket = new UdtSocket(this->Parent(), this->ObjectName());
68  acceptedSocket->blockOnSend = this->blockOnSend;
69  acceptedSocket->blockOnReceive = this->blockOnReceive;
70
71  sockaddr_in their_addr;
72  int namelen = sizeof(their_addr);
73
74  if ((acceptedSocket->socket = UDT::accept(socket, (sockaddr *)&their_addr,
75                                            &namelen)) == UDT::INVALID_SOCK) {
76    Err("accept: %s, code %i\n", UDT::getlasterror().getErrorMessage(),
77        UDT::getlasterror().getErrorCode());
78  }
79
80  return acceptedSocket;
81}
82
83bool UdtSocket::Connect(const unsigned int port,
84                        const std::string distantAddress, Time timeout) {
85  bool success = true;
86  socket = UDT::socket(AF_INET, SOCK_DGRAM, 0);
87
88  UDT::setsockopt(socket, 0, UDT_SNDSYN, &blockOnSend, sizeof(bool));
89  UDT::setsockopt(socket, 0, UDT_RCVSYN, &blockOnReceive, sizeof(bool));
90  bool reuse = true;
91  UDT::setsockopt(socket, 0, UDT_REUSEADDR, &reuse, sizeof(bool));
92
93  sockaddr_in serv_addr;
94  serv_addr.sin_family = AF_INET;
95  serv_addr.sin_port = htons(short(port));
96  if (inet_pton(AF_INET, distantAddress.c_str(), &serv_addr.sin_addr) <= 0) {
97    printf("incorrect network address.");
98    success = false;
99  }
100  memset(&(serv_addr.sin_zero), '\0', 8);
101
102  if (UDT::ERROR ==
103      UDT::connect(socket, (sockaddr *)&serv_addr, sizeof(serv_addr))) {
104    success = false;
105  }
106  if (!success) {
107    UDT::close(socket);
108    return false;
109  } else
110    return true;
111}
112
113ssize_t UdtSocket::SendMessage(const char *buffer, size_t bufferSize,
114                               Time timeout) {
115  int udtTimeout = timeout;
116  if (blockOnSend) {
117    if (UDT::setsockopt(socket, 0, UDT_SNDTIMEO, &udtTimeout,
118                        sizeof(udtTimeout)) != 0)
119      Err("error UDT_SNDTIMEO %s\n", UDT::getlasterror().getErrorMessage());
120  }
121  ssize_t bytesSent = UDT::sendmsg(socket, buffer, bufferSize, -1, true);
122
123  return bytesSent;
124}
125
126ssize_t UdtSocket::RecvMessage(char *buffer, size_t bufferSize, Time timeout) {
127  int udtTimeout = timeout;
128  if (blockOnReceive) {
129    if (UDT::setsockopt(socket, 0, UDT_RCVTIMEO, &udtTimeout,
130                        sizeof(udtTimeout)) != 0)
131      Err("error UDT_RCVTIMEO %s\n", UDT::getlasterror().getErrorMessage());
132  }
133  ssize_t bytesRead = UDT::recvmsg(socket, buffer, bufferSize);
134
135  /*
136      if(bytesRead<0) {
137          if(UDT::getlasterror().getErrorCode()==CUDTException::ECONNLOST) {
138              connection_lost=true;
139          }
140      }
141  */
142  return bytesRead;
143}
144
145uint16_t UdtSocket::NetworkToHost16(uint16_t data) { return ntohs(data); }
146
147uint16_t UdtSocket::HostToNetwork16(uint16_t data) { return htons(data); }
148
149uint32_t UdtSocket::NetworkToHost32(uint32_t data) { return ntohl(data); }
150
151uint32_t UdtSocket::HostToNetwork32(uint32_t data) { return htonl(data); }
152
153} // end namespace core
154} // end namespace flair
Note: See TracBrowser for help on using the repository browser.