COSMOS core  1.0.2 (beta)
Comprehensive Open-architecture Solution for Mission Operations Systems

#include <socketlib.h>

Collaboration diagram for Udp:

Public Member Functions

 Udp ()
 
int32_t socketOpen ()
 Open UDP socket. More...
 
int32_t setupClient ()
 
int32_t setupClient (string a, uint16_t p)
 
int32_t setupClientSimGen (string a, uint16_t p)
 
int32_t setupClientAcstb (string a, uint16_t p)
 
int32_t setupServer (uint16_t port, float timeout_sec)
 
int32_t send (string package2send)
 
int32_t receiveLoop ()
 
int32_t receiveOnce ()
 
int32_t close ()
 

Public Attributes

string receivedData
 

Private Member Functions

int32_t openServer ()
 
int32_t errorStatus (string functionName)
 

Private Attributes

SocketOptions sok
 
int32_t iretn = 0
 

Constructor & Destructor Documentation

Udp::Udp ( )
1102  {
1103  // default values (for Matlab)
1104  //sok.address = "127.0.0.1";
1105  //sok.port = 8888;
1106 
1107  //sok("127.0.0.1",8888);
1108  //sok {"127.0.0.1",8888};
1109  //iretn = init();
1110 }

Member Function Documentation

int32_t Udp::openServer ( )
private
int32_t Udp::errorStatus ( string  functionName)
private
1133  {
1134 
1135 #ifdef COSMOS_WIN_OS
1136  errno = WSAGetLastError();
1137  std::cout << functionName << " failed with error code :" << errno << " (" << strerror(errno) << ")" << std::endl;
1138  std::cout << "Check the Windows Sockets Error Codes to get more information: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx" << std::endl;
1139 #else
1140  std::cout << functionName << " failed with error code :" << errno << " (" << strerror(errno) << ")" << std::endl;
1141 #endif
1142 
1143  // return negative error number
1144  return -errno;
1145  //exit(EXIT_FAILURE);
1146 }
int32_t Udp::socketOpen ( )

Open UDP socket.

Open a UDP socket and configure it for the specified use. Various flags are set, and the socket is bound, if necessary. Support is provided for the extra steps necessary for MS Windows.

Returns
Zero, or negative error.
  1. Join multicast
766 {
767  socklen_t namelen;
768  int32_t iretn;
769  struct ip_mreq mreq;
770  int on = 1;
771  int debug = false; //turn on or off debug statements
772 
773 #ifdef COSMOS_WIN_OS
774  unsigned long nonblocking = 1;
775  struct sockaddr_storage ss;
776  int sslen;
777  WORD wVersionRequested;
778  WSADATA wsaData;
779  static bool started=false;
780 
781  //Initialise winsock
782  if (debug){std::cout << "\nInitialising Winsock...";}
783  if (!started)
784  {
785  wVersionRequested = MAKEWORD( 1, 1 );
786  //wVersionRequested = MAKEWORD( 2, 2 );
787  //iretn = WSAStartup( wVersionRequested, &wsaData );
788 
789  if ( (iretn=WSAStartup(wVersionRequested,&wsaData)) != 0)
790  {
791  if (debug){printf("Failed. Error Code : %d",WSAGetLastError());
792  return errno;
793  }
794  }
795  if (debug){std::cout << "Initialised." << std::endl;}
796  }
797 #endif
798 
799  //Create a socket
800  if (sok.stream){
801  if ((sok.handle = socket(AF_INET, SOCK_STREAM,0)) <0){
802  {
803  if (debug){
804 #ifdef COSMOS_WIN_OS
805  printf("Could not create socket stream: %d" , WSAGetLastError());
806 #else
807  printf("Could not create socket stream : %d" , errno);
808 #endif
809  }
810  return (-errno);
811  }
812  }
813  } else {
814  //default
815  if ((sok.handle = socket(AF_INET, SOCK_DGRAM,0)) <0){
816  {
817  if (debug){
818 #ifdef COSMOS_WIN_OS
819  printf("Could not create socket : %d" , WSAGetLastError());
820 #else
821  printf("Could not create socket : %d" , errno);
822 #endif
823  }
824  return (-errno);
825  }
826  }
827  }
828 
829  if (debug){std::cout << "Socket created" << std::endl;}
830 
832  {
833  iretn = 0;
834 #ifdef COSMOS_WIN_OS
835  if (ioctlsocket(sok.handle, FIONBIO, &nonblocking) != 0)
836  {
837  iretn = -WSAGetLastError();
838  }
839 #else
840  if (fcntl(sok.handle, F_SETFL,O_NONBLOCK) < 0)
841  {
842  iretn = -errno;
843  }
844 #endif
845  if (iretn < 0)
846  {
847  CLOSE_SOCKET(sok.handle);
848  sok.handle = iretn;
849  return iretn;
850  }
851  }
852 
853  // this defines the wait time for a response from a request
854  if (sok.timeout)
855  {
856 #ifdef COSMOS_WIN_OS
857  int msectimeo = sok.timeout/1000;
858  iretn = setsockopt(sok.handle,SOL_SOCKET,SO_RCVTIMEO,(const char *)&msectimeo,sizeof(msectimeo));
859 #else
860  struct timeval tv;
861  tv.tv_sec = sok.timeout/1000000;
862  tv.tv_usec = sok.timeout%1000000;
863  iretn = setsockopt(sok.handle,SOL_SOCKET,SO_RCVTIMEO,(char*)&tv,sizeof(tv));
864 #endif
865  }
866 
867  //Prepare the sockaddr_in structure
868  memset(&sok.server, 0, sizeof(struct sockaddr_in));
869  sok.server.sin_family = AF_INET;
870  sok.server.sin_port = htons(sok.port);
871 
872  switch (sok.role)
873  {
874  case SOCKET_LISTEN:
875 #ifdef COSMOS_MAC_OS
876  if (setsockopt(sok.handle,SOL_SOCKET,SO_REUSEPORT,(char*)&on,sizeof(on)) < 0)
877 #else
878  if (setsockopt(sok.handle,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on)) < 0)
879 #endif
880  {
881  CLOSE_SOCKET(sok.handle);
882  sok.handle = -errno;
883  return (-errno);
884  }
885 
886  sok.server.sin_addr.s_addr = htonl(INADDR_ANY);
887 
888  //Bind
889  if (::bind(sok.handle,(struct sockaddr *)&sok.server, sok.addrlen) < 0) //addrlen = sizeof(struct sockaddr_in)
890  {
891  if (debug){
892 #ifdef COSMOS_WIN_OS
893  printf("Bind failed with error code : %d" , WSAGetLastError());
894 #endif
895  }
896 
897  CLOSE_SOCKET(sok.handle);
898  sok.handle = -errno;
899  return (-errno);
900  }
901  if (debug){std::cout << "Bind done" << std::endl;}
902 
903  // If we bound to port 0, then find out what our assigned port is.
904  if (!sok.port)
905  {
906  namelen = sizeof(struct sockaddr_in);
907  if ((iretn = getsockname(sok.handle, (sockaddr*)&sok.server, &namelen)) == -1)
908  {
909  CLOSE_SOCKET(sok.handle);
910  sok.handle = -errno;
911  return (-errno);
912  }
913  sok.port = ntohs(sok.server.sin_port);
914  }
915  else
916  {
917  //>>
918  //port = port;
919  }
920 
922  {
924  mreq.imr_multiaddr.s_addr = inet_addr(sok.address.c_str());
925  mreq.imr_interface.s_addr = htonl(INADDR_ANY);
926  if (setsockopt(sok.handle, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) < 0)
927  {
928  CLOSE_SOCKET(sok.handle);
929  sok.handle = -errno;
930  return (-errno);
931  }
932  }
933 
934 
935  break;
936  case SOCKET_JABBER:
937  switch (sok.type)
938  {
939  case NetworkType::UDP:
940  if ((iretn=setsockopt(sok.handle,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0)
941  {
942  CLOSE_SOCKET(sok.handle);
943  sok.handle = -errno;
944  return (-errno);
945  }
946  sok.server.sin_addr.s_addr = 0xffffffff;
947  break;
949 #ifndef COSMOS_WIN_OS
950  inet_pton(AF_INET,sok.address.c_str(),&sok.server.sin_addr);
951 #else
952  sslen = sizeof(ss);
953  WSAStringToAddressA((LPSTR)sok.address.c_str(),AF_INET,NULL,(struct sockaddr*)&ss,&sslen);
954  sok.server.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
955 #endif
956  break;
957  default:
958  return (SOCKET_ERROR_PROTOCOL);
959  break;
960  }
961  // >>
962  //port = port;
963  break;
964  //------------------------------------------------------
965  case SOCKET_TALK:
966 #ifndef COSMOS_WIN_OS
967  inet_pton(AF_INET,sok.address.c_str(),&sok.server.sin_addr);
968 #else
969  sslen = sizeof(ss);
970  WSAStringToAddressA((LPSTR)sok.address.c_str(),AF_INET,NULL,(struct sockaddr*)&ss,&sslen);
971  sok.server.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
972 #endif
973  //>>
974  //port = port;
975 
976  if (sok.connect){
977  if ((iretn=connect(sok.handle, (struct sockaddr *)&sok.server, sok.addrlen)) < 0)
978  {
979 #ifdef COSMOS_WIN_OS
980  iretn = WSAGetLastError();
981  if (iretn != WSAEWOULDBLOCK)
982  {
983  return (errno);
984  }
985 #else
986  iretn = errno;
987  if (iretn != EINPROGRESS)
988  {
989  return (errno);
990  }
991 #endif
992  COSMOS_SLEEP(1);
993  }
994  }
995 
996 
997  break;
998  }
999 
1000  return 0;
1001 }
bool connect
Definition: socketlib.h:178
Agent socket using Unicast UDP.
int32_t iretn
Definition: socketlib.h:221
#define SOCKET_ERROR_PROTOCOL
Definition: cosmos-errno.h:230
NetworkType type
Definition: socketlib.h:171
string address
Definition: socketlib.h:181
#define SOCKET_NONBLOCKING
Non-blocking Agent.
Definition: socketlib.h:80
#define SOCKET_TALK
Talk followed by optional listen (sendto address)
Definition: socketlib.h:82
int addrlen
Definition: socketlib.h:186
int32_t handle
Definition: socketlib.h:173
bool blocking
Definition: socketlib.h:189
bool stream
Definition: socketlib.h:192
uint16_t role
Definition: socketlib.h:188
uint16_t port
Definition: socketlib.h:183
uint32_t timeout
Definition: socketlib.h:190
static bool debug
Definition: agent_antenna.cpp:164
#define SOCKET_LISTEN
Listen followed by optional talk (recvfrom INADDRANY)
Definition: socketlib.h:84
#define SOCKET_JABBER
Talk over multiple interfaces.
Definition: socketlib.h:88
Agent socket using Multicast UDP.
struct sockaddr_in server
Definition: socketlib.h:175
SocketOptions sok
Definition: socketlib.h:218
int32_t Udp::setupClient ( )
1007  {
1008  return socketOpen();
1009 }
int32_t socketOpen()
Open UDP socket.
Definition: socketlib.cpp:765
int32_t Udp::setupClient ( string  a,
uint16_t  p 
)
1011  {
1012  // config
1013  sok.address = a;
1014  sok.port = p;
1015 
1016  return socketOpen();
1017 }
string address
Definition: socketlib.h:181
static double * p
Definition: gauss_jackson_test.cpp:42
uint16_t port
Definition: socketlib.h:183
Definition: eci2kep_test.cpp:33
int32_t socketOpen()
Open UDP socket.
Definition: socketlib.cpp:765
SocketOptions sok
Definition: socketlib.h:218
int32_t Udp::setupClientSimGen ( string  a,
uint16_t  p 
)
1019  {
1020  // config
1021  sok.address = a;
1022  sok.port = p;
1024  sok.stream = true;
1025  sok.timeout = 0;
1026  sok.connect = true;
1027 
1028  return socketOpen();
1029 }
bool connect
Definition: socketlib.h:178
string address
Definition: socketlib.h:181
#define SOCKET_NONBLOCKING
Non-blocking Agent.
Definition: socketlib.h:80
static double * p
Definition: gauss_jackson_test.cpp:42
bool blocking
Definition: socketlib.h:189
bool stream
Definition: socketlib.h:192
uint16_t port
Definition: socketlib.h:183
uint32_t timeout
Definition: socketlib.h:190
Definition: eci2kep_test.cpp:33
int32_t socketOpen()
Open UDP socket.
Definition: socketlib.cpp:765
SocketOptions sok
Definition: socketlib.h:218
int32_t Udp::setupClientAcstb ( string  a,
uint16_t  p 
)
1031  {
1032  // config
1033  sok.address = a;
1034  sok.port = p;
1036  sok.stream = true;
1037  sok.timeout = 0;
1038  sok.connect = true;
1039 
1040  return socketOpen();
1041 
1042 }
bool connect
Definition: socketlib.h:178
string address
Definition: socketlib.h:181
#define SOCKET_NONBLOCKING
Non-blocking Agent.
Definition: socketlib.h:80
static double * p
Definition: gauss_jackson_test.cpp:42
bool blocking
Definition: socketlib.h:189
bool stream
Definition: socketlib.h:192
uint16_t port
Definition: socketlib.h:183
uint32_t timeout
Definition: socketlib.h:190
Definition: eci2kep_test.cpp:33
int32_t socketOpen()
Open UDP socket.
Definition: socketlib.cpp:765
SocketOptions sok
Definition: socketlib.h:218
int32_t Udp::setupServer ( uint16_t  port,
float  timeout_sec 
)
1064  {
1065  // the sok.server does not need an ip because it runs on the
1066  // local computer (with preassigned ip)
1067  sok.port = port;
1071  sok.timeout = timeout_sec*1000000;
1072 
1073  // int socket_timeout = 0;
1074  // if (timeout == 0){
1075  // socket_timeout = SOCKET_RCVTIMEO;
1076  // } else {
1077  // socket_timeout = timeout;
1078  // }
1079 
1080  if ((iretn=socketOpen()) < 0)
1081  {
1082  return (-errno);
1083  }
1084  return 0;
1085 }
static string port
Definition: add_radio.cpp:16
Agent socket using Unicast UDP.
int32_t iretn
Definition: socketlib.h:221
NetworkType type
Definition: socketlib.h:171
bool blocking
Definition: socketlib.h:189
uint16_t role
Definition: socketlib.h:188
uint16_t port
Definition: socketlib.h:183
#define SOCKET_BLOCKING
Blocking Agent.
Definition: socketlib.h:78
uint32_t timeout
Definition: socketlib.h:190
#define SOCKET_LISTEN
Listen followed by optional talk (recvfrom INADDRANY)
Definition: socketlib.h:84
int32_t socketOpen()
Open UDP socket.
Definition: socketlib.cpp:765
SocketOptions sok
Definition: socketlib.h:218
int32_t Udp::send ( string  package2send)
1148  {
1149 
1150  if (sendto(sok.handle, // socket
1151  package2send.c_str(), // buffer to send
1152  strlen(package2send.c_str()), // size of buffer
1153  0, // flags
1154  (struct sockaddr *)&sok.server, // socket address
1155  sok.addrlen) // size of address to socket pointer //sizeof(struct sockaddr_in))
1156  < 0){
1157 
1158  return errorStatus("Udp::send");
1159  }
1160  //std::cout << "sent: " << package2send << std::endl;
1161  // return 0 on sucess
1162  return 0;
1163 }
int32_t errorStatus(string functionName)
Definition: socketlib.cpp:1133
int addrlen
Definition: socketlib.h:186
int32_t handle
Definition: socketlib.h:173
struct sockaddr_in server
Definition: socketlib.h:175
SocketOptions sok
Definition: socketlib.h:218
int32_t Udp::receiveLoop ( )
1240  {
1241  char buf[SOCKET_BUFFER_LENGTH];
1242  int recv_len;
1243 
1244  //keep listening for data
1245  std::cout << "Waiting for data...";
1246 
1247  while(1){
1248 
1249  //clear the buffer by filling null, it might have previously received data
1250  memset(buf,'\0', SOCKET_BUFFER_LENGTH);
1251 
1252  //try to receive some data, this is a blocking call
1253  if ((recv_len = recvfrom(sok.handle,
1254  buf,
1256  0,
1257  (struct sockaddr *) &sok.s_other,
1258  (socklen_t *)&sok.addrlen)) < 0){
1259  return errorStatus("Udp::receiveLoop");
1260  }
1261 
1262  if (recv_len > 0) {
1263  //print details of the client/peer and the data received
1264  std::cout << "Received packet from " << inet_ntoa(sok.server.sin_addr) << ":" << ntohs(sok.port) << std::endl;
1265  std::cout << "Data: " << buf << std::endl;
1266  recv_len = 0;
1267  }
1268 
1269  //now reply the client with the same data
1270  if (sendto(sok.handle,
1271  buf,
1272  recv_len,
1273  0,
1274  (struct sockaddr*) &sok.s_other,
1275  sok.addrlen) < 0){
1276  return errorStatus("Udp::receiveLoop");
1277  }
1278 
1279  }
1280 
1281 
1282  return 0;
1283 }
int32_t errorStatus(string functionName)
Definition: socketlib.cpp:1133
int addrlen
Definition: socketlib.h:186
int32_t handle
Definition: socketlib.h:173
uint16_t port
Definition: socketlib.h:183
struct sockaddr_in s_other
Definition: socketlib.h:176
char buf[128]
Definition: rw_test.cpp:40
#define SOCKET_BUFFER_LENGTH
Definition: socketlib.h:105
struct sockaddr_in server
Definition: socketlib.h:175
SocketOptions sok
Definition: socketlib.h:218
int32_t Udp::receiveOnce ( )
1167  {
1168  // collects the data from the Udp channel
1169  // and puts into the receivedData string
1170  // that is defined on the Udp class
1171  char buf[SOCKET_BUFFER_LENGTH];
1172  int recv_len = -1;
1173 
1174  //keep listening for data
1175  //std::cout << "Waiting for data...";
1176 
1177  //clear the buffer by filling null, it might have previously received data
1178  memset(buf,'\0', SOCKET_BUFFER_LENGTH);
1179 
1180 
1181  ElapsedTime ep;
1182  ep.print = false;
1183  ep.tic();
1184  float timeout = 5.0; // seconds
1185  double timer = -1.;
1186 
1187  // just to test timer
1188  //COSMOS_SLEEP(0.001);
1189 
1190  while ( (recv_len < 0) && (timer < timeout) ){
1191  // keep trying to receive message
1192  //receivedStatus = udp.receiveOnce();
1193 
1194  //try to receive some data
1195  recv_len = recvfrom(sok.handle,
1196  buf,
1198  0,
1199  (struct sockaddr *) &sok.s_other,
1200  (socklen_t *)&sok.addrlen);
1201 
1202  timer = ep.toc();
1203  //std::cout << recv_len << " | " << timer << std::endl;
1204  //std::cout << " (udp rx: " << recv_len << " bytes | " << timer << " sec)" << std::endl;
1205 
1206 
1207  if (recv_len < 0)
1208  {
1209 #ifdef COSMOS_WIN_OS
1210  if (WSAGetLastError() == 10035){
1211  //std::cout << "Resource temporarily unavailable. Continue." << std::endl;
1212  continue;
1213  }
1214 #endif
1215  return errorStatus("Udp::receiveOnce");
1216  //continue;
1217  }
1218 
1219  if (recv_len > 0) {
1220  //print details of the client/peer and the data received
1221  // std::cout << "Received packet from " << inet_ntoa(sok.server.sin_addr) << ":" << ntohs(sok.port) << std::endl;
1222  // std::cout << "Data: " << buf << std::endl;
1223 
1224  //std::cout << std::endl << "<< udp rx: " << recv_len << " bytes | " << std::setprecision(3) << std::fixed << timer << " sec" << std::endl;
1225 
1226  recv_len = 0;
1227  timer = 0;
1228  receivedData = string(buf);
1229  return 0;
1230  }
1231  //
1232  }
1233 
1234  std::cout << "Failed to receive data in less than 5 sec. Elapsed time: " << ep.toc() << std::endl;
1235  return -1;
1236 }
int32_t errorStatus(string functionName)
Definition: socketlib.cpp:1133
int addrlen
Definition: socketlib.h:186
int32_t handle
Definition: socketlib.h:173
bool print
Definition: elapsedtime.h:97
void tic()
ElapsedTime::tic, equivalent to matlab to start a stopwatch timer.
Definition: elapsedtime.cpp:166
Definition: elapsedtime.h:62
struct sockaddr_in s_other
Definition: socketlib.h:176
double toc()
ElapsedTime::toc, equivalent to matlab to stop a stopwatch timer.
Definition: elapsedtime.cpp:174
char buf[128]
Definition: rw_test.cpp:40
#define SOCKET_BUFFER_LENGTH
Definition: socketlib.h:105
SocketOptions sok
Definition: socketlib.h:218
string receivedData
Definition: socketlib.h:253
int32_t Udp::close ( )
1286  {
1287 
1288 #ifdef COSMOS_WIN_OS
1289  closesocket(sok.handle);
1290  WSACleanup();
1291 #endif
1292 
1293  return 0;
1294 }
int32_t handle
Definition: socketlib.h:173
SocketOptions sok
Definition: socketlib.h:218

Member Data Documentation

SocketOptions Udp::sok
private
int32_t Udp::iretn = 0
private
string Udp::receivedData

The documentation for this class was generated from the following files: