nidas v1.2.3
McSocket.h
Go to the documentation of this file.
1// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4; -*-
2// vim: set shiftwidth=4 softtabstop=4 expandtab:
3/*
4 ********************************************************************
5 ** NIDAS: NCAR In-situ Data Acquistion Software
6 **
7 ** 2006, Copyright University Corporation for Atmospheric Research
8 **
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License as published by
11 ** the Free Software Foundation; either version 2 of the License, or
12 ** (at your option) any later version.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
18 **
19 ** The LICENSE.txt file accompanying this software contains
20 ** a copy of the GNU General Public License. If it is not found,
21 ** write to the Free Software Foundation, Inc.,
22 ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 **
24 ********************************************************************
25 */
26
27#ifndef NIDAS_UTIL_MCSOCKET_H
28#define NIDAS_UTIL_MCSOCKET_H
29
30#include <nidas/Config.h> // HAVE_PPOLL
31
32#include "Socket.h"
33#include "DatagramPacket.h"
34#include "Thread.h"
35#include "UTime.h"
36
37#ifdef HAVE_PPOLL
38#include <poll.h>
39#else
40#include <sys/select.h>
41#endif
42
43#include <list>
44
45#include <unistd.h> // need declaration of sleep()
46
47namespace nidas { namespace util {
48
50
54 int magic;
62
67 unsigned short _listenPort;
68
73
77 McSocketData() : magic(0),_requestType(htonl((unsigned)-1)),_listenPort(0),_socketType(htons(SOCK_STREAM)) {}
78};
79
87class McSocketDatagram: public DatagramPacketT<McSocketData>
88{
89public:
90 McSocketDatagram(int requestType=-1);
91
96
101
102 int getMagic() const { return ntohl(mcdata.magic); }
103
104 void setMagic(int val) { mcdata.magic = htonl(val); }
105
106 int getRequestType() const { return ntohl(mcdata._requestType); }
107
108 void setRequestType(int val) { mcdata._requestType = htonl(val); }
109
113 int getRequesterListenPort() const { return ntohs(mcdata._listenPort); }
114
115 void setRequesterListenPort(int val) { mcdata._listenPort = htons(val); }
116
121 int getSocketType() const { return ntohs(mcdata._socketType); }
122
123 void setSocketType(int val) { mcdata._socketType = htons(val); }
124
129 static const int magicVal;
130
131protected:
133};
134
135
136template <class SocketT>
137class McSocket;
138
139inline int getMcSocketType(McSocket<Socket>*)
140{
141 return SOCK_STREAM;
142}
143
144inline int getMcSocketType(McSocket<DatagramSocket>*)
145{
146 return SOCK_DGRAM;
147}
148
190template <class SocketT>
192{
197 friend class McSocketListener;
198
199 template<class SocketTT>
201public:
272
276 McSocket(const McSocket<SocketT>&);
277
281 McSocket<SocketT>& operator=(const McSocket<SocketT>& rhs);
282
283 virtual ~McSocket();
284
296 _iface = iaddr;
297 }
298
300
306 std::list<Inet4NetworkInterface> getInterfaces() const;
307
312 {
313 return _mcastAddr;
314 }
315
321
328 void setRequestType(int val) { _requestType = val; }
329
333 int getRequestType() const { return _requestType; }
334
350 void listen();
351
366
377 virtual void connected(SocketT*,const Inet4PacketInfoX&) {}
378
388 void request();
389
400
406 virtual void close();
407
408private:
418 void offer(SocketT* sock,const Inet4PacketInfoX& pktinfo);
419
420 void offer(int err);
421
423
425
427
429
431
432 SocketT* _newsocket;
433
435
437
439
444
446
447 // Inet4PacketInfoX _pktinfo;
448
449};
450
459{
460 template<class SocketT>
461 friend class McSocket;
462
463public:
464
468 static int check() throw();
469
470private:
482 static void accept(McSocket<Socket>* sock);
483
495 static void accept(McSocket<DatagramSocket>* sock);
496
504 static void close(McSocket<Socket>* sock);
505
513 static void close(McSocket<DatagramSocket>* sock);
514
518 int run();
519
520 void interrupt();
521
522private:
524
526
527 void add(McSocket<Socket>* mcsocket);
528
529 void add(McSocket<DatagramSocket>* mcsocket);
530
531 int remove(McSocket<Socket>* mcsocket);
532
533 int remove(McSocket<DatagramSocket>* mcsocket);
534
537
540
541private:
542
544
546
548
550
552
553};
554
562template<class SocketTT>
564{
565 template<class SocketT>
566 friend class McSocket;
567
568private:
569 McSocketMulticaster(McSocket<SocketTT>* mcsocket);
570
573
576
577 virtual ~McSocketMulticaster();
578
582 int run();
583
584 void interrupt();
585
586 McSocket<SocketTT>* _mcsocket;
587
593
599
604
606};
607
608}} // namespace nidas namespace util
609
610#include "Logger.h"
611#include <memory>
612
613namespace nidas { namespace util {
614
615template<class SocketT>
616McSocket<SocketT>::McSocket(): _mcastAddr(),_iface(),_requestType(-1),
617 _connectCond(),
618 _newsocket(0),_newpktinfo(),
619 _socketOffered(false),_offerErrno(0),
620 _multicaster(0),_multicaster_mutex()
621{
622}
623
624template<class SocketT>
625McSocket<SocketT>::McSocket(const McSocket<SocketT>& x) :
626 _mcastAddr(x._mcastAddr),_iface(x._iface),
627 _requestType(x._requestType), _connectCond(),
628 _newsocket(0),_newpktinfo(),
629 _socketOffered(false),_offerErrno(0),
630 _multicaster(0),_multicaster_mutex()
631{
632}
633
634template<class SocketT>
635McSocket<SocketT>& McSocket<SocketT>::operator=(const McSocket<SocketT>& rhs)
636{
637 if (&rhs != this) {
638 _mcastAddr = rhs._mcastAddr;
639 _iface = rhs._iface;
640 _requestType = rhs._requestType;
641 _newsocket = 0;
642 _socketOffered = false;
643 _multicaster = 0;
644 }
645 return *this;
646}
647
648template<class SocketT>
651
652template<class SocketT>
653std::list<Inet4NetworkInterface> McSocket<SocketT>::getInterfaces() const
654{
655 MulticastSocket tmpsock(_mcastAddr.getPort());
656 std::list<Inet4NetworkInterface> ifcs = tmpsock.getInterfaces();
657 tmpsock.close();
658 return ifcs;
659}
660
661template<class SocketT>
663{
664 if (getRequestType() < 0)
665 throw IOException(_mcastAddr.toString(), "listen",
666 "request number has not been set");
667 _connectCond.lock();
668 _newsocket = 0;
669 _socketOffered = false;
670 _connectCond.unlock();
671 try {
673 }
674 catch (const Exception& e) {
675 throw IOException(_mcastAddr.toString(), "accept", e.what());
676 }
677}
678
679/*
680 * Does a listen and then waits for the connection.
681 */
682template<class SocketT>
684{
685 listen();
686 _connectCond.lock();
687 while(!_socketOffered) _connectCond.wait();
688 SocketT* socket = _newsocket;
689 pktinfo = _newpktinfo;
690 _newsocket = 0;
691 _connectCond.unlock();
692 VLOG(("accept offerErrno=%d", _offerErrno));
693 if (!socket) throw IOException("McSocket","accept",_offerErrno);
694 return socket;
695}
696
697template<class SocketT>
699{
700 if (getRequestType() < 0)
701 throw IOException(_mcastAddr.toString(),"listen",
702 "request number has not been set");
703 _connectCond.lock();
704 _newsocket = 0;
705 _socketOffered = false;
706 _connectCond.unlock();
707 // if (!_mcastAddr.getInet4Address().isMultiCastAddress())
708 // throw IOException(_mcastAddr.toString(),"accept","is not a multicast address");
709
710 _multicaster_mutex.lock();
711 if (!_multicaster) {
712 _multicaster = new McSocketMulticaster<SocketT>(this);
713 try {
714 _multicaster->start();
715 }
716 catch(const Exception& e) {
717 throw IOException("McSocket","request",e.what());
718 }
719 }
720 _multicaster_mutex.unlock();
721}
722
723/*
724 * Does a request() and then waits for the connection.
725 */
726template<class SocketT>
728{
729 request();
730 _connectCond.lock();
731 while(!_socketOffered) _connectCond.wait();
732 SocketT* socket = _newsocket;
733 pktinfo = _newpktinfo;
734 _newsocket = 0;
735 _connectCond.unlock();
736 VLOG(("connect offerErrno=%d",_offerErrno));
737 if (!socket) throw IOException("McSocket","connect",_offerErrno);
738 return socket;
739}
740
741template<class SocketT>
743{
744 // can't do a multicaster->join here, that would deadlock
745 // because we'd be waiting for ourselves,
746 // so we spawn a detached thread to join and delete it.
747
748 _multicaster_mutex.lock();
749
750 if (_multicaster) {
751 VLOG(("Mcsocket::offer creating/starting joiner"));
752 ThreadJoiner* joiner = new ThreadJoiner(_multicaster);
753 _multicaster = 0;
754 try {
755 joiner->start();
756 }
757 // shouldn't happen
758 catch(const Exception& e) {
759 Logger::getInstance()->log(LOG_ERR,"%s",e.what());
760 }
761 VLOG(("Mcsocket::offer joiner started"));
762 }
763 VLOG(("Mcsocket::offer doing connectCond.lock"));
764 _multicaster_mutex.unlock();
765}
766/*
767 * Method that executes in the thread of the McSocketListener
768 * or the McSocketMulticaster, and notifies whoever did
769 * the listen() or request() that the socket is connected.
770 */
771template<class SocketT>
772void McSocket<SocketT>::offer(SocketT* socket,const Inet4PacketInfoX& pktinfo)
773{
774 joinMulticaster();
775
776 if (socket) connected(socket,pktinfo);
777
778 _connectCond.lock();
779 _socketOffered = true;
780 _offerErrno = 0;
781 _newsocket = socket;
782 _newpktinfo = pktinfo;
783 _connectCond.signal();
784 _connectCond.unlock();
785
786 // note: don't access any class variables or virtual methods
787 // after the above unlock. The calling thread may have
788 // deleted this object after it received the connected Socket.
789}
790
791template<class SocketT>
793{
794 joinMulticaster();
795
796 _connectCond.lock();
797 _socketOffered = true;
798 _offerErrno = err;
799 _newsocket = 0;
800 _connectCond.signal();
801 _connectCond.unlock();
802
803 // note: don't access any class variables or virtual methods
804 // after the above unlock. The calling thread may have
805 // deleted this object after it received the connected Socket.
806}
807
808template<class SocketT>
810{
811 VLOG(("Mcsocket::close"));
812 _multicaster_mutex.lock();
813 if (_multicaster && _multicaster->isRunning()) _multicaster->interrupt();
814 _multicaster_mutex.unlock();
815
816 offer(EINTR);
817
818 try {
820 }
821 catch (const Exception& e) {
822 VLOG(("Mcsocket::close exception: %s", e.what()));
823 throw IOException(_mcastAddr.toString(), "close", e.what());
824 }
825 VLOG(("Mcsocket::close done, this=0x%x", this));
826}
827
828template<class SocketTT>
830 Thread("McSocketMulticaster"),
831 _mcsocket(mcsock),_serverSocket(0),_datagramSocket(0),_requestSocket(0),
832 _mcsocketMutex()
833{
834 switch (getMcSocketType(mcsock)) {
835 case SOCK_STREAM:
837 _datagramSocket = 0;
838 break;
839 default:
841 _serverSocket = 0;
842 break;
843 }
844 // block SIGUSR1, then unblock it in pselect/ppoll
845 blockSignal(SIGUSR1);
846}
847
848template<class SocketT>
850{
851 if (_serverSocket) {
852 _serverSocket->close();
853 delete _serverSocket;
854 }
855 if (_datagramSocket) {
856 _datagramSocket->close();
857 delete _datagramSocket;
858 }
859 if (_requestSocket) {
860 _requestSocket->close();
861 delete _requestSocket;
862 }
863}
864
865template<class SocketT>
867{
868 _mcsocketMutex.lock();
869 _mcsocket = 0;
870 _mcsocketMutex.unlock();
871 try {
872 kill(SIGUSR1);
873 }
874 catch(const Exception& e) {
875 PLOG(("%s",e.what()));
876 }
877}
878
879
880void
882 std::vector<Inet4NetworkInterface>& ifaces);
883
884template<class SocketT>
886{
887 MulticastSocket* requestmsock = 0;
888
889 int sockfd = (_serverSocket ? _serverSocket->getFd() :
890 _datagramSocket->getFd());
891
892#ifdef HAVE_PPOLL
893 struct pollfd fds;
894 fds.fd = sockfd;
895#ifdef POLLRDHUP
896 fds.events = POLLIN | POLLRDHUP;
897#else
898 fds.events = POLLIN;
899#endif
900#else
901 fd_set fdset;
902 FD_ZERO(&fdset);
903#endif
904
905 // wait for this amount of time after a datagram send to receive a
906 // connection or receipt of UDP data
907 struct timespec timeout;
908 timeout.tv_sec = 0;
909 timeout.tv_nsec = NSECS_PER_SEC / 4; // portion of a second
910
911 // get the existing signal mask
912 sigset_t sigmask;
913 pthread_sigmask(SIG_BLOCK,NULL,&sigmask);
914 // unblock SIGUSR1 in pselect/ppoll
915 sigdelset(&sigmask,SIGUSR1);
916
917 Inet4SocketAddress mcsockaddr =
918 _mcsocket->getInet4McastSocketAddress();
919 Inet4Address mcaddr = mcsockaddr.getInet4Address();
920
921 std::vector<Inet4NetworkInterface> ifaces;
922
923 if (mcaddr.isMultiCastAddress())
924 {
925 VLOG(("") << mcsockaddr.toString() << " is a multicast address.");
926 _requestSocket = requestmsock = new MulticastSocket();
927 if (_mcsocket->getInterface().getAddress() == Inet4Address(INADDR_ANY))
928 {
929 listMulticastInterfaces(requestmsock, ifaces);
930 }
931 }
932 else
933 {
934 VLOG(("") << mcsockaddr.toString()
935 << " is not a multicast address, using a datagram request socket.");
936 _requestSocket = new DatagramSocket();
937 }
938
939 McSocketDatagram dgram;
940 dgram.setMagic(dgram.magicVal);
941 dgram.setSocketAddress(mcsockaddr);
942 dgram.setRequestType(_mcsocket->getRequestType());
943 dgram.setSocketType(getMcSocketType(_mcsocket));
944 if (_serverSocket)
945 dgram.setRequesterListenPort(_serverSocket->getLocalPort());
946 else
947 dgram.setRequesterListenPort(_datagramSocket->getLocalPort());
948
949 for (int numCasts=0; !isInterrupted() ; numCasts++) {
950 // If multicast, loop over interfaces
951 try {
952 if (requestmsock && ifaces.size() > 0) {
953 Inet4NetworkInterface iface = ifaces[numCasts % ifaces.size()];
954 requestmsock->setInterface(mcaddr,iface);
955 _requestSocket->send(dgram);
956 }
957 else {
958 _requestSocket->send(dgram);
959 }
960 if (!(numCasts % 300)) {
961 ILOG(("") << "sent " << numCasts << " dgrams" <<
962 ", requestType=" << dgram.getRequestType() <<
963 ", port=" << dgram.getRequesterListenPort() <<
964 ", socketType=" << dgram.getSocketType() <<
965 ", len=" << dgram.getLength() <<
966 ", #mcifaces=" << ifaces.size());
967 }
968 }
969 catch(const IOException& e)
970 {
971 // perhaps the interface has disappeared. Log the error.
972 WLOG(("McSocketMulticaster: ")
973 << _requestSocket->getLocalSocketAddress().toString()
974 << ": " << e.what());
975 sleep(10);
976 if (requestmsock)
977 {
978 _requestSocket->close();
979 delete _requestSocket;
980 // close and re-create the socket
981 _requestSocket = requestmsock = new MulticastSocket();
982 // re-create the list of interfaces.
983 listMulticastInterfaces(requestmsock, ifaces);
984 }
985 continue;
986 }
987
988 int res;
989#ifdef HAVE_PPOLL
990 res = ::ppoll(&fds,1,&timeout,&sigmask);
991
992 if (res > 0) {
993
994 if (fds.revents & POLLERR) {
995 _mcsocketMutex.lock();
996 if (_mcsocket) _mcsocket->offer(errno);
997 _mcsocketMutex.unlock();
998 if (_serverSocket) _serverSocket->close(); // OK to close twice
999 if (_datagramSocket) _datagramSocket->close();
1000 _requestSocket->close();
1001 throw IOException("McSocket","ppoll",errno);
1002 }
1003
1004#ifdef POLLRDHUP
1005 if (fds.revents & (POLLHUP | POLLRDHUP))
1006#else
1007 if (fds.revents & POLLHUP)
1008#endif
1009 WLOG(("%s POLLHUP","McSocket"));
1010
1011 }
1012
1013#else
1014 assert(sockfd >= 0 && sockfd < FD_SETSIZE); // FD_SETSIZE=1024
1015 FD_SET(sockfd, &fdset);
1016 res = ::pselect(sockfd+1,&fdset,0,0,&timeout,&sigmask);
1017#endif
1018 if (res <= 0) {
1019 if (res == 0) continue;
1020 if (errno == EINTR) break;
1021 _mcsocketMutex.lock();
1022 if (_mcsocket) _mcsocket->offer(errno);
1023 _mcsocketMutex.unlock();
1024 if (_serverSocket) _serverSocket->close(); // OK to close twice
1025 if (_datagramSocket) _datagramSocket->close();
1026 _requestSocket->close();
1027 throw IOException("McSocket","poll/select",errno);
1028 }
1029
1030 if (_serverSocket) {
1031 Socket* socket = _serverSocket->accept();
1032 DLOG(("accepted socket connection from ") <<
1033 socket->getRemoteSocketAddress().toString() << " on " <<
1034 _serverSocket->getLocalSocketAddress().toString());
1035 _serverSocket->close();
1037 if (socket->getRemoteSocketAddress().getFamily() == AF_INET) {
1039 nidas::util::Inet4SocketAddress((const struct sockaddr_in*)
1040 socket->getRemoteSocketAddress().getConstSockAddrPtr());
1041 pktinfo.setRemoteSocketAddress(remoteAddr);
1042 }
1043 if (socket->getLocalSocketAddress().getFamily() == AF_INET) {
1045 nidas::util::Inet4SocketAddress((const struct sockaddr_in*)
1046 socket->getLocalSocketAddress().getConstSockAddrPtr());
1047 pktinfo.setLocalAddress(localAddr.getInet4Address());
1048 pktinfo.setDestinationAddress(localAddr.getInet4Address());
1049 }
1050 _mcsocketMutex.lock();
1051 if (_mcsocket) _mcsocket->offer((SocketT*)socket,pktinfo);
1052 _mcsocketMutex.unlock();
1053 }
1054 else {
1055 // If fishing for UDP responses, send out at least 3 multicasts
1056 // to see if we get more than one response.
1057 if (numCasts < 3) continue;
1058
1059 // We know there is data at the socket, do a MSG_PEEK to get
1060 // information about the first packet.
1062 _datagramSocket->receive(dgram,pktinfo,MSG_PEEK);
1063 if (dgram.getSocketAddress().getFamily() == AF_INET) {
1065 nidas::util::Inet4SocketAddress((const struct sockaddr_in*)
1066 dgram.getSocketAddress().getConstSockAddrPtr());
1067 pktinfo.setRemoteSocketAddress(remoteAddr);
1068 }
1069
1070 _mcsocketMutex.lock();
1071 if (_mcsocket) _mcsocket->offer((SocketT*)_datagramSocket,pktinfo);
1072 _datagramSocket = 0; // we no longer own _datagramSocket
1073 _mcsocketMutex.unlock();
1074 }
1075 _requestSocket->close();
1076 return RUN_OK;
1077 } // loop until receipt of connection or UDP packet
1078
1079 VLOG(("McSocketMulticaster break"));
1080 _mcsocketMutex.lock();
1081 if (_mcsocket) _mcsocket->offer(EINTR);
1082 _mcsocketMutex.unlock();
1083 if (_serverSocket) _serverSocket->close();
1084 if (_datagramSocket) _datagramSocket->close();
1085 _requestSocket->close();
1086 VLOG(("McSocketMulticaster run method exiting"));
1087 return RUN_OK;
1088}
1089
1090}} // namespace nidas namespace util
1091#endif
Header file for the nidas::util logging facility.
#define err(format, arg...)
Definition ck_lams.cc:55
A wrapper class for a Posix condition variable.
Definition ThreadSupport.h:258
A DatagramPacket with a specific structure of data.
Definition DatagramPacket.h:178
A socket for sending or receiving datagrams, either unicast, broadcast or multicast.
Definition Socket.h:1178
Definition Exception.h:35
Definition IOException.h:37
Support for IP version 4 host address.
Definition Inet4Address.h:46
Definition Inet4NetworkInterface.h:36
Definition Inet4PacketInfo.h:93
A IP version 4 socket address, containing a host address, and a port number.
Definition Inet4SocketAddress.h:41
static Logger * getInstance()
Retrieve the current Logger singleton instance.
Definition Logger.cc:318
Datagram that is multicast by a host when it wants a service.
Definition McSocket.h:88
void setRequestType(int val)
Definition McSocket.h:108
struct McSocketData mcdata
Definition McSocket.h:132
int getMagic() const
Definition McSocket.h:102
McSocketDatagram & operator=(const McSocketDatagram &rhs)
Assignment operator.
Definition McSocket.cc:68
void setMagic(int val)
Definition McSocket.h:104
int getRequesterListenPort() const
What port is the requester listening on for the connection back?
Definition McSocket.h:113
void setSocketType(int val)
Definition McSocket.h:123
int getRequestType() const
Definition McSocket.h:106
static const int magicVal
Magic value that should be found at the beginning of all received McSocketDatagrams.
Definition McSocket.h:129
void setRequesterListenPort(int val)
Definition McSocket.h:115
McSocketDatagram(int requestType=-1)
Definition McSocket.cc:50
int getSocketType() const
What socket type does the requester want to establish? SOCK_STREAM or SOCK_DGRAM.
Definition McSocket.h:121
Class for listening on McSocket requests on a specific multicast address and UDP port number.
Definition McSocket.h:459
int run()
Definition McSocket.cc:292
static int check()
Public method to return the number of McSocketListeners that are active.
Definition McSocket.cc:195
void add(McSocket< Socket > *mcsocket)
Definition McSocket.cc:217
std::map< int, McSocket< Socket > * > _tcpMcSockets
Definition McSocket.h:549
static void close(McSocket< Socket > *sock)
Remove the given McSocket from the list being served by this listener.
Definition McSocket.cc:135
void interrupt()
Interrupt this thread.
Definition McSocket.cc:281
Mutex _mcsocket_mutex
Definition McSocket.h:545
DatagramSocket * _readsock
Definition McSocket.h:547
int remove(McSocket< Socket > *mcsocket)
Definition McSocket.cc:241
std::map< int, McSocket< DatagramSocket > * > _udpMcSockets
Definition McSocket.h:551
static void accept(McSocket< Socket > *sock)
How a McSocket<Socket> registers with a McSocketListener.
Definition McSocket.cc:81
Inet4SocketAddress _mcastAddr
Definition McSocket.h:543
Thread which is started by McSocket to multicast requests for connections.
Definition McSocket.h:564
McSocketMulticaster(const McSocketMulticaster &)
No copying.
int run()
Definition McSocket.h:885
McSocketMulticaster(McSocket< SocketTT > *mcsocket)
Definition McSocket.h:829
Mutex _mcsocketMutex
Definition McSocket.h:605
DatagramSocket * _requestSocket
The DatagramSocket that requests are sent on.
Definition McSocket.h:603
void interrupt()
Interrupt this thread.
Definition McSocket.h:866
McSocketMulticaster & operator=(const McSocketMulticaster &)
No assignment.
virtual ~McSocketMulticaster()
Definition McSocket.h:849
McSocket< SocketTT > * _mcsocket
Definition McSocket.h:586
DatagramSocket * _datagramSocket
If multicasting for a UDP connection, then _datagramSocket will point to the UDP socket that is waiti...
Definition McSocket.h:598
ServerSocket * _serverSocket
If multicasting for a TCP connection, then _serverSocket will point to the TCP socket that listening ...
Definition McSocket.h:592
A McSocket provides a way to establish a TCP stream socket connection, or a pair of UDP datagram sock...
Definition McSocket.h:192
void joinMulticaster()
Definition McSocket.h:742
McSocket< SocketT > & operator=(const McSocket< SocketT > &rhs)
Assignment operator.
Definition McSocket.h:635
int getRequestType() const
Get the request type number.
Definition McSocket.h:333
void offer(SocketT *sock, const Inet4PacketInfoX &pktinfo)
How a McSocketListener passes back a connected TCP socket or DatagramSocket.
Definition McSocket.h:772
void request()
Start issuing requests for a connection by multicasting McSocketDatagrams.
Definition McSocket.h:698
const Inet4SocketAddress & getInet4McastSocketAddress() const
Get the multicast address for listening to requests.
Definition McSocket.h:311
virtual void close()
Unregister this McSocket from the multicasting and listening threads.
Definition McSocket.h:809
std::list< Inet4NetworkInterface > getInterfaces() const
Return all network interfaces on this system.
Definition McSocket.h:653
SocketT * _newsocket
Definition McSocket.h:432
void setInterface(Inet4NetworkInterface iaddr)
Set a specific interface for the multicasts.
Definition McSocket.h:295
Inet4PacketInfoX _newpktinfo
Definition McSocket.h:434
McSocket()
Create a McSocket for requesting or accepting multicast requests for a socket connection.
Definition McSocket.h:616
void setInet4McastSocketAddress(const Inet4SocketAddress &val)
Set the multicast address for listening to requests.
Definition McSocket.h:320
int _requestType
Definition McSocket.h:428
Inet4SocketAddress _mcastAddr
Definition McSocket.h:424
void setRequestType(int val)
Set the request type value.
Definition McSocket.h:328
McSocket(const McSocket< SocketT > &)
Copy constructor.
Definition McSocket.h:625
virtual ~McSocket()
Definition McSocket.h:649
Inet4NetworkInterface getInterface() const
Definition McSocket.h:299
int _offerErrno
Definition McSocket.h:438
bool _socketOffered
Definition McSocket.h:436
Cond _connectCond
Definition McSocket.h:430
Mutex _multicaster_mutex
Definition McSocket.h:445
SocketT * accept(Inet4PacketInfoX &)
Like ServerSocket::accept(), this method will return a connected socket.
Definition McSocket.h:683
virtual void connected(SocketT *, const Inet4PacketInfoX &)
Virtual method that is called when a socket connection is established.
Definition McSocket.h:377
void listen()
Register with a McSocketListener to listen on the multicast address.
Definition McSocket.h:662
void offer(int err)
Definition McSocket.h:792
SocketT * connect(Inet4PacketInfoX &)
Do a request(), and then wait until a TCP connection is established, or a UDP datagram is received ba...
Definition McSocket.h:727
Thread * _multicaster
The thread we start which multicasts for connections.
Definition McSocket.h:443
Inet4NetworkInterface _iface
Definition McSocket.h:426
A datagram socket to be used for multicasts.
Definition Socket.h:1582
A C++ wrapper for a POSIX mutex.
Definition ThreadSupport.h:161
A stream (TCP) socket that is used to listen for connections.
Definition Socket.h:981
A stream (TCP) socket.
Definition Socket.h:573
const SocketAddress & getRemoteSocketAddress() const
Get remote address of this socket.
Definition Socket.h:893
const SocketAddress & getLocalSocketAddress() const
Get local address of this socket.
Definition Socket.h:912
In certain situations one needs to "join oneself", which would be a deadlock.
Definition Thread.h:608
Definition Thread.h:83
void blockSignal(int)
Block a signal in this thread.
Definition Thread.cc:181
#define WLOG(MSG)
Definition Logger.h:313
#define PLOG(MSG)
Definition Logger.h:312
#define DLOG(MSG)
Definition Logger.h:316
#define VLOG(MSG)
Definition Logger.h:317
#define ILOG(MSG)
Definition Logger.h:315
#define LOG_ERR
Definition Logger.h:216
int getMcSocketType(McSocket< Socket > *)
Definition McSocket.h:139
void listMulticastInterfaces(MulticastSocket *requestmsock, std::vector< Inet4NetworkInterface > &ifaces)
Definition McSocket.cc:472
Root namespace for the NCAR In-Situ Data Acquisition Software.
Definition A2DConverter.h:31
Definition McSocket.h:49
McSocketData()
Constructor.
Definition McSocket.h:77
int magic
Magic value that should be found at the beginning of all received datagrams.
Definition McSocket.h:54
unsigned short _listenPort
Socket port that the remote host is listening on.
Definition McSocket.h:67
short _socketType
Either SOCK_STREAM=1, or SOCK_DGRAM=2.
Definition McSocket.h:72
int _requestType
An integer which identifies the type of the request.
Definition McSocket.h:61
#define NSECS_PER_SEC
Definition types.h:98