// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} // created: 2015/04/21 // filename: UdtSocket.cpp // // author: Gildas Bayard // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: Class defining a UDT socket // // /*********************************************************************/ #include "UdtSocket.h" #include #include #include #include #include using std::string; namespace flair { namespace core { UdtSocket::UdtSocket(const Object* parent,const std::string name,bool _blockOnSend,bool _blockOnReceive):ConnectedSocket(parent,name) { UDT::startup(); blockOnSend=_blockOnSend; blockOnReceive=_blockOnReceive; } UdtSocket::~UdtSocket(){ } void UdtSocket::Listen(const unsigned int port,const std::string localAddress) { socket = UDT::socket(AF_INET, SOCK_DGRAM, 0); UDT::setsockopt(socket, 0, UDT_SNDSYN, &blockOnSend, sizeof(bool)); UDT::setsockopt(socket, 0, UDT_RCVSYN, &blockOnReceive, sizeof(bool)); bool reuse = true; UDT::setsockopt(socket, 0, UDT_REUSEADDR, &reuse, sizeof(bool)); sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port); if (localAddress=="ANY") { my_addr.sin_addr.s_addr=INADDR_ANY; } else { inet_aton(localAddress.c_str(),&(my_addr.sin_addr)); } memset(&(my_addr.sin_zero), '\0', 8); if (UDT::ERROR == UDT::bind(socket, (sockaddr*)&my_addr, sizeof(my_addr))) { Err("bind, %s\n",UDT::getlasterror().getErrorMessage()); } UDT::listen(socket, 1); } UdtSocket *UdtSocket::Accept(Time timeout) { // TIMEOUT UNSUPPORTED!! UdtSocket *acceptedSocket=new UdtSocket(this->Parent(),this->ObjectName()); acceptedSocket->blockOnSend=this->blockOnSend; acceptedSocket->blockOnReceive=this->blockOnReceive; sockaddr_in their_addr; int namelen = sizeof(their_addr); if ((acceptedSocket->socket = UDT::accept(socket, (sockaddr*)&their_addr, &namelen))==UDT::INVALID_SOCK) { Err("accept: %s, code %i\n",UDT::getlasterror().getErrorMessage(),UDT::getlasterror().getErrorCode()); } return acceptedSocket; } bool UdtSocket::Connect(const unsigned int port,const std::string distantAddress,Time timeout) { bool success=true; socket=UDT::socket(AF_INET, SOCK_DGRAM, 0); UDT::setsockopt(socket, 0, UDT_SNDSYN, &blockOnSend, sizeof(bool)); UDT::setsockopt(socket, 0, UDT_RCVSYN, &blockOnReceive, sizeof(bool)); bool reuse = true; UDT::setsockopt(socket, 0, UDT_REUSEADDR, &reuse, sizeof(bool)); sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(short(port)); if (inet_pton(AF_INET, distantAddress.c_str(), &serv_addr.sin_addr) <= 0) { printf("incorrect network address."); success=false; } memset(&(serv_addr.sin_zero), '\0', 8); if (UDT::ERROR == UDT::connect(socket, (sockaddr*)&serv_addr, sizeof(serv_addr))) { success=false; } if (!success) { UDT::close(socket); return false; } else return true; } ssize_t UdtSocket::SendMessage(const char* buffer,size_t bufferSize,Time timeout){ int udtTimeout=timeout; if (blockOnSend) { if(UDT::setsockopt(socket, 0, UDT_SNDTIMEO, &udtTimeout, sizeof(udtTimeout))!=0) Err("error UDT_SNDTIMEO %s\n", UDT::getlasterror().getErrorMessage()); } ssize_t bytesSent=UDT::sendmsg(socket, buffer, bufferSize, -1,true); return bytesSent; } ssize_t UdtSocket::RecvMessage(char* buffer,size_t bufferSize,Time timeout){ int udtTimeout=timeout; if (blockOnReceive) { if(UDT::setsockopt(socket, 0, UDT_RCVTIMEO, &udtTimeout, sizeof(udtTimeout))!=0) Err("error UDT_RCVTIMEO %s\n", UDT::getlasterror().getErrorMessage()); } ssize_t bytesRead= UDT::recvmsg(socket,buffer,bufferSize); /* if(bytesRead<0) { if(UDT::getlasterror().getErrorCode()==CUDTException::ECONNLOST) { connection_lost=true; } } */ return bytesRead; } uint16_t UdtSocket::NetworkToHost16(uint16_t data) { return ntohs(data); } uint16_t UdtSocket::HostToNetwork16(uint16_t data) { return htons(data); } uint32_t UdtSocket::NetworkToHost32(uint32_t data) { return ntohl(data); } uint32_t UdtSocket::HostToNetwork32(uint32_t data) { return htonl(data); } } // end namespace core } // end namespace flair