41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
51 #include <arpa/inet.h>
69 SocketStreamElem::SocketStreamElem(
unsigned int uL,
70 const std::string& name,
74 int flags,
bool bSendFirst,
bool bAbortIfBroken,
78 pUS(pUS), pSC(pSC), send_flags(flags),
79 bSendFirst(bSendFirst), bAbortIfBroken(bAbortIfBroken),
87 SocketStreamElem::~SocketStreamElem(
void)
103 SocketStreamElem::Restart(std::ostream& out)
const
105 return out <<
"# SocketStreamElem(" << GetLabel() <<
"): "
106 "not implemented yet" << std::endl;
116 OutputCounter = OutputEvery - 1;
118 AfterConvergence(X, XP);
131 if (pUS->Abandoned()) {
139 if (OutputCounter != OutputEvery) {
155 int save_errno = errno;
157 if (save_errno == EAGAIN && (send_flags & MSG_DONTWAIT)) {
162 char *
msg = strerror(save_errno);
163 silent_cerr(
"SocketStreamElem(" << name <<
"): send() failed "
164 "(" << save_errno <<
": " << msg <<
")"
167 if (bAbortIfBroken) {
179 AfterConvergence(X, XP);
202 #if defined(HAVE_GETADDRINFO)
203 struct addrinfo hints,*res;
205 #elif defined(HAVE_GETHOSTBYNAME)
207 #elif defined(HAVE_INET_ATON)
209 #endif // ! HAVE_GETADDRINFO && ! HAVE_GETHOSTBYNAME && ! HAVE_INET_ATON
227 #else // ! USE_SOCKET
228 static const int sock_stream = 1;
229 static const int sock_dgram = 2;
230 #endif // ! USE_SOCKET
252 socketStreamOutputDataTmp.
bIsRTAI =
false;
254 if (::rtmbdyn_rtai_task != 0) {
255 socketStreamOutputDataTmp.
bIsRTAI =
true;
259 if (!socketStreamOutputDataTmp.
bIsRTAI) {
260 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
261 "not allowed because apparently the current "
262 "architecture does not support sockets "
266 #endif // ! USE_SOCKET
268 socketStreamOutputDataTmp.
port = (
unsigned short int)(-1);
269 socketStreamOutputDataTmp.
bCreate =
false;
270 bool bGotCreate(
false);
275 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
276 "unable to read stream name "
280 }
else if (socketStreamOutputDataTmp.
bIsRTAI && strlen(m) != 6) {
281 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
282 "illegal stream name \"" << m <<
"\" "
283 "(must be exactly 6 chars) "
288 socketStreamOutputDataTmp.
name = m;
291 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
292 "missing stream name "
294 if (socketStreamOutputDataTmp.
bIsRTAI) {
302 silent_cerr(
"SocketStreamElem(" << uLabel <<
"):"
303 "\"create\" must be either "
315 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
316 "unable to read local path "
321 socketStreamOutputDataTmp.
path = m;
325 if (!socketStreamOutputDataTmp.
path.empty()) {
326 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
327 "cannot specify a port for a local socket "
335 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
336 "illegal port " << p <<
" "
341 socketStreamOutputDataTmp.
port = p;
345 if (!socketStreamOutputDataTmp.
path.empty()) {
346 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
347 "cannot specify an allowed host "
348 "for a local socket "
357 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
358 "unable to read host "
363 socketStreamOutputDataTmp.
host = h;
365 }
else if (socketStreamOutputDataTmp.
path.empty() && !socketStreamOutputDataTmp.
bCreate) {
367 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
371 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
372 "using default host: "
373 << socketStreamOutputDataTmp.
host <<
":"
374 << (socketStreamOutputDataTmp.
port == (
unsigned short int)(-1) ?
DEFAULT_PORT : socketStreamOutputDataTmp.
port)
384 socketStreamOutputDataTmp.
bCreate =
true;
388 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
389 "invalid socket type "
395 if (socketStreamOutputDataTmp.
socket_type == sock_dgram && socketStreamOutputDataTmp.
bCreate) {
396 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
397 "socket type=udp incompatible with create=yes "
403 socketStreamOutputDataTmp.
bNoSignal =
false;
408 socketStreamOutputDataTmp.
bNoSignal =
true;
411 socketStreamOutputDataTmp.
bNoSignal =
false;
416 }
else if (HP.
IsKeyWord(
"non" "blocking")) {
419 }
else if (HP.
IsKeyWord(
"no" "send" "first")) {
422 }
else if (HP.
IsKeyWord(
"send" "first")) {
425 }
else if (HP.
IsKeyWord(
"abort" "if" "broken")) {
428 }
else if (HP.
IsKeyWord(
"do" "not" "abort" "if" "broken")) {
440 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
441 "invalid output every value " << i <<
" "
453 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
454 "semicolon expected "
464 <<
"outputelement: " << uLabel
467 if (socketStreamOutputDataTmp.
bIsRTAI) {
469 if (socketStreamOutputDataTmp.
pSOE != 0) {
470 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
471 "echo ignored in RTAI mode"
475 unsigned long node = (
unsigned long)-1;
476 #if defined(HAVE_GETADDRINFO)
477 socketStreamOutputDataTmp.hints = {0};
478 socketStreamOutputDataTmp.res = null;
480 socketStreamOutputDataTmp.hints.ai_family = AF_INET;
481 socketStreamOutputDataTmp.hints.ai_socktype = SOCK_STREAM;
482 socketStreamOutputDataTmp.rc = getaddrinfo(socketStreamOutputDataTmp.
host.c_str(), NULL, &(socketStreamOutputDataTmp.hints), &(socketStreamOutputDataTmp.res));
483 if (socketStreamOutputDataTmp.rc == 0) {
484 node = ((
struct sockaddr_in *)(socketStreamOutputDataTmp.res)->ai_addr)->sin_addr.s_addr;
485 freeaddrinfo(socketStreamOutputDataTmp.res);
487 #elif defined(HAVE_GETHOSTBYNAME)
488 socketStreamOutputDataTmp.he = gethostbyname(socketStreamOutputDataTmp.
host.c_str());
489 if (socketStreamOutputDataTmp.he != NULL) {
490 node = ((
unsigned long *)(socketStreamOutputDataTmp.he)->h_addr_list[0])[0];
492 #elif defined(HAVE_INET_ATON)
493 if (inet_aton(socketStreamOutputDataTmp.
host.c_str(), &(socketStreamOutputDataTmp.addr))) {
494 node = socketStreamOutputDataTmp.addr.s_addr;
496 #else // ! HAVE_GETADDRINFO && ! HAVE_GETHOSTBYNAME && ! HAVE_INET_ATON
497 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
498 "host (RTAI RPC) not supported "
501 #endif // ! HAVE_GETADDRINFO && ! HAVE_GETHOSTBYNAME && ! HAVE_INET_ATON
503 if (node == (
unsigned long)-1) {
504 silent_cerr(
"RTMBDynInDrive(" << uLabel <<
"): "
505 "unable to convert host \"" <<
host <<
"\" to node" << std::endl);
509 silent_cerr(
"starting RTMBDynOutputElement(" << uLabel <<
")..."
513 socketStreamOutputDataTmp.
name, socketStreamOutputDataTmp.
host, node,
514 socketStreamOutputDataTmp.
bCreate, socketStreamOutputDataTmp.
pSC, socketStreamOutputDataTmp.
bNonBlocking));
528 socketStreamOutputDataTmp.
flags = 0;
533 if (socketStreamOutputDataTmp.
path.empty()) {
534 if (socketStreamOutputDataTmp.
port == (
unsigned short int)(-1)) {
536 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
537 "port undefined; using default port "
538 << socketStreamOutputDataTmp.
port <<
" at line "
543 socketStreamOutputDataTmp.
port, socketStreamOutputDataTmp.
socket_type, socketStreamOutputDataTmp.
bCreate));
548 <<
" " << socketStreamOutputDataTmp.
name
549 <<
" " << socketStreamOutputDataTmp.
host
550 <<
" " << socketStreamOutputDataTmp.
port;
551 if (socketStreamOutputDataTmp.
socket_type == sock_dgram) {
556 out <<
" " << socketStreamOutputDataTmp.
bCreate;
566 <<
" " << socketStreamOutputDataTmp.
name
567 <<
" " << socketStreamOutputDataTmp.
path;
568 if (socketStreamOutputDataTmp.
socket_type == sock_dgram) {
573 out <<
" " << socketStreamOutputDataTmp.
bCreate;
576 if (socketStreamOutputDataTmp.
bCreate) {
577 pDM->RegisterSocketUser(pUS);
584 if (socketStreamOutputDataTmp.
bNoSignal) {
591 #else // !MSG_NOSIGNAL
592 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
593 "MSG_NOSIGNAL undefined; "
594 "your mileage may vary" << std::endl);
595 #endif // !MSG_NOSIGNAL
600 socketStreamOutputDataTmp.
flags |= MSG_DONTWAIT;
603 socketStreamOutputDataTmp.
flags &= ~MSG_DONTWAIT;
605 #else // !MSG_DONTWAIT
606 silent_cerr(
"SocketStreamElem(" << uLabel <<
"): "
607 "MSG_DONTWAIT undefined; "
608 "your mileage may vary" << std::endl);
609 #endif // !MSG_DONTWAIT
611 silent_cerr(
"starting SocketStreamElem(" << uLabel <<
")..."
614 SocketStreamElem(uLabel, socketStreamOutputDataTmp.
name, socketStreamOutputDataTmp.
OutputEvery,
615 pUS, socketStreamOutputDataTmp.
pSC, socketStreamOutputDataTmp.
flags,
617 socketStreamOutputDataTmp.
pSOE));
620 <<
" " << (!socketStreamOutputDataTmp.
bNoSignal)
622 <<
" " << socketStreamOutputDataTmp.
bSendFirst
650 const unsigned uFlags = pSCM->
uGetFlags();
659 for (std::vector<const StructNode*>::const_iterator i = pSCM->
nodes_begin();
662 out <<
" " << (*i)->GetLabel();
void WriteStreamContentLogOutput(const StreamContent *pSC, std::ostream &out)
const unsigned uGetFlags(void) const
#define MBDYN_EXCEPT_ARGS
virtual integer GetInt(integer iDefval=0)
void Echo(const doublereal *pbuf, unsigned nChannels)
void * GetBuf(void) const
virtual const char * GetFileName(enum Delims Del=DEFAULTDELIM)
virtual Elem * createSocketStreamOutElem(DataManager *pDM, MBDynParser &HP, unsigned int uLabel, StreamContent::Type type, SocketStreamOutputDataTmp &socketStreamOutputDataTmp)
std::vector< Hint * > Hints
static const int sock_dgram
std::vector< const StructNode * >::const_iterator nodes_begin(void) const
virtual unsigned GetNumChannels(void) const =0
bool Init(const std::string &msg, unsigned uLabel, unsigned nChannels)
StreamContent * ReadStreamContent(DataManager *pDM, MBDynParser &HP, StreamContent::Type type)
StreamOutEcho * ReadStreamOutEcho(MBDynParser &HP)
virtual bool IsKeyWord(const char *sKeyWord)
Elem * ReadSocketStreamElem(DataManager *pDM, MBDynParser &HP, unsigned int uLabel, StreamContent::Type type)
virtual void Prepare(void)=0
virtual void getSocketStreamOutParam(DataManager *pDM, MBDynParser &HP, unsigned int uLabel, StreamContent::Type type, SocketStreamOutputDataTmp &socketStreamOutputDataTmp)
virtual const char * GetStringWithDelims(enum Delims Del=DEFAULTDELIM, bool escape=true)
#define ASSERT(expression)
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
std::vector< const StructNode * >::const_iterator nodes_end(void) const
const void * GetOutBuf(void) const
virtual bool GetYesNo(bool &bRet)
std::ostream & GetLogFile(void) const
virtual HighParser::ErrOut GetLineData(void) const
static const int sock_stream
int GetOutSize(void) const