41#if defined(_MSC_VER) || defined(__MINGW32__)
43#elif defined(__OpenBSD__)
45#include <sys/socket.h>
68#if defined(_MSC_VER) || defined(__MINGW32__)
72 if (WSAStartup(MAKEWORD(1, 1), &wsaData)) {
73 cerr <<
"Winsock DLL not initialized ..." << endl;
78 cout <<
"Winsock DLL loaded ..." << endl;
89 struct addrinfo *addr =
nullptr;
90 this->precision = precision;
92 #if defined(_MSC_VER) || defined(__MINGW32__)
96 struct addrinfo hints;
97 memset(&hints, 0,
sizeof(
struct addrinfo));
98 hints.ai_family = AF_INET;
99 if (protocol ==
ptUDP)
100 hints.ai_socktype = SOCK_DGRAM;
102 hints.ai_socktype = SOCK_STREAM;
103 hints.ai_protocol = 0;
105 hints.ai_flags = AI_ADDRCONFIG;
107 hints.ai_flags = AI_NUMERICHOST;
109 int failure = getaddrinfo(address.c_str(), NULL, &hints, &addr);
110 if (failure || !addr) {
111 cerr <<
"Could not get host net address " << address;
113 if (hints.ai_flags == AI_NUMERICHOST)
114 cerr <<
" by number..." << endl;
116 cerr <<
" by name..." << endl;
118 cerr << gai_strerror(failure) << endl;
124 sckt = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
127 if (protocol ==
ptUDP)
128 cout <<
"Creating UDP socket on port " << port << endl;
130 cout <<
"Creating TCP socket on port " << port << endl;
134 int len =
sizeof(
struct sockaddr_in);
135 memcpy(&scktName, addr->ai_addr, len);
136 scktName.sin_port = htons(port);
138 if (connect(sckt, (
struct sockaddr*)&scktName, len) == 0) {
140 cout <<
"Successfully connected to socket for output ..." << endl;
143 cerr <<
"Could not connect to socket for output ..." << endl;
145 cerr <<
"Could not create socket for FDM output, error = " << errno << endl;
160 this->precision = precision;
162#if defined(_MSC_VER) || defined(__MINGW32__)
166 if (Protocol ==
ptUDP) {
167 ProtocolName =
"UDP";
168 sckt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
169#if defined(_MSC_VER) || defined(__MINGW32__)
171 ioctlsocket(sckt, FIONBIO, &NonBlock);
173 fcntl(sckt, F_SETFL, O_NONBLOCK);
177 ProtocolName =
"TCP";
178 sckt = socket(AF_INET, SOCK_STREAM, 0);
182 cout <<
"Creating input " << ProtocolName <<
" socket on port " << port
186 memset(&scktName, 0,
sizeof(
struct sockaddr_in));
187 scktName.sin_family = AF_INET;
188 scktName.sin_port = htons(port);
190 if (Protocol ==
ptUDP)
191 scktName.sin_addr.s_addr = htonl(INADDR_ANY);
193 int len =
sizeof(
struct sockaddr_in);
194 if (bind(sckt, (
struct sockaddr*)&scktName, len) != -1) {
196 cout <<
"Successfully bound to " << ProtocolName
197 <<
" input socket on port " << port << endl << endl;
199 if (Protocol ==
ptTCP) {
200 if (listen(sckt, 5) >= 0) {
201#if defined(_MSC_VER) || defined(__MINGW32__)
203 ioctlsocket(sckt, FIONBIO, &NoBlock);
204 sckt_in = accept(sckt, (
struct sockaddr*)&scktName, &len);
206 int flags = fcntl(sckt, F_GETFL, 0);
207 fcntl(sckt, F_SETFL, flags | O_NONBLOCK);
208 sckt_in = accept(sckt, (
struct sockaddr*)&scktName, (socklen_t*)&len);
212 cerr <<
"Could not listen ..." << endl;
216 cerr <<
"Could not bind to " << ProtocolName <<
" input socket, error = "
219 cerr <<
"Could not create " << ProtocolName <<
" socket for input, error = "
229 if (sckt) shutdown(sckt,2);
230 if (sckt_in) shutdown(sckt_in,2);
239 int len =
sizeof(
struct sockaddr_in);
244 if (sckt_in <= 0 && Protocol ==
ptTCP) {
245 #if defined(_MSC_VER) || defined(__MINGW32__)
246 sckt_in = accept(sckt, (
struct sockaddr*)&scktName, &len);
248 sckt_in = accept(sckt, (
struct sockaddr*)&scktName, (socklen_t*)&len);
251 #if defined(_MSC_VER) || defined(__MINGW32__)
253 ioctlsocket(sckt_in, FIONBIO, &NoBlock);
255 int flags = fcntl(sckt_in, F_GETFL, 0);
256 fcntl(sckt_in, F_SETFL, flags | O_NONBLOCK);
258 send(sckt_in,
"Connected to JSBSim server\nJSBSim> ", 35, 0);
263 while ((num_chars = recv(sckt_in, buf,
sizeof buf, 0)) > 0) {
264 data.append(buf, num_chars);
270 if (num_chars == 0) {
271 DWORD err = WSAGetLastError ();
272 if (err != WSAEWOULDBLOCK) {
273 printf (
"Socket Closed. back to listening\n");
274 closesocket (sckt_in);
282 if (sckt >= 0 && Protocol ==
ptUDP) {
283 struct sockaddr addr;
284 socklen_t fromlen =
sizeof addr;
285 num_chars = recvfrom(sckt, buf,
sizeof buf, 0, (
struct sockaddr*)&addr, &fromlen);
286 if (num_chars != -1) data.append(buf, num_chars);
296 int num_chars_sent=0;
299 num_chars_sent = send(sckt_in, text.c_str(), text.size(), 0);
300 send(sckt_in,
"JSBSim> ", 8, 0);
302 cerr <<
"Socket reply must be to a valid socket" << endl;
305 return num_chars_sent;
319 buffer.str(
string());
334 if (buffer.tellp() > 0) buffer <<
',';
342 if (buffer.tellp() > 0) buffer <<
',';
343 buffer << std::setw(12) << std::setprecision(precision) << item;
350 if (buffer.tellp() > 0) buffer <<
',';
351 buffer << std::setw(12) << item;
359 string str = buffer.str();
360 if ((send(sckt,str.c_str(),str.size(),0)) <= 0) {
369 if ((send(sckt,data,length,0)) <= 0) {
383 FD_SET(sckt_in, &fds);
384 select(sckt_in+1, &fds, NULL, NULL, NULL);
416void FGfdmSocket::Debug(
int from)
425 if (from == 0) cout <<
"Instantiated: FGfdmSocket" << endl;
426 if (from == 1) cout <<
"Destroyed: FGfdmSocket" << endl;
int Reply(const std::string &text)
void Append(const std::string &s)
void WaitUntilReadable(void)
FGfdmSocket(const std::string &address, int port, int protocol, int precision=7)
std::string Receive(void)
bool is_number(const std::string &str)