24 typedef int socklen_t;
27 #include <sys/types.h>
28 #include <sys/socket.h>
32 #include <arpa/inet.h>
34 #include <netinet/in.h>
43 static bool initialized =
false;
49 throw() : userMessage(message) {
51 userMessage.append(
": ");
52 userMessage.append(strerror(errno));
60 return userMessage.c_str();
64 static void fillAddr(
const string &address,
unsigned short port,
66 memset(&addr, 0,
sizeof(addr));
67 addr.sin_family = AF_INET;
70 if ((host = gethostbyname(address.c_str())) == NULL) {
75 addr.sin_addr.s_addr = *((
unsigned long *) host->h_addr_list[0]);
77 addr.sin_port = htons(port);
85 WORD wVersionRequested;
88 wVersionRequested = MAKEWORD(2, 0);
89 if (WSAStartup(wVersionRequested, &wsaData) != 0) {
97 if ((sockDesc = socket(PF_INET, type, protocol)) < 0) {
103 this->sockDesc = sockDesc;
117 unsigned int addr_len =
sizeof(addr);
119 if (getsockname(sockDesc, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) {
120 throw SocketException(
"Fetch of local address failed (getsockname())",
true);
122 return inet_ntoa(addr.sin_addr);
127 unsigned int addr_len =
sizeof(addr);
129 if (getsockname(sockDesc, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) {
130 throw SocketException(
"Fetch of local port failed (getsockname())",
true);
132 return ntohs(addr.sin_port);
137 sockaddr_in localAddr;
138 memset(&localAddr, 0,
sizeof(localAddr));
139 localAddr.sin_family = AF_INET;
140 localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
141 localAddr.sin_port = htons(localPort);
143 if (bind(sockDesc, (sockaddr *) &localAddr,
sizeof(sockaddr_in)) < 0) {
151 sockaddr_in localAddr;
152 fillAddr(localAddress, localPort, localAddr);
154 if (bind(sockDesc, (sockaddr *) &localAddr,
sizeof(sockaddr_in)) < 0) {
155 throw SocketException(
"Set of local address and port failed (bind())",
true);
161 if (WSACleanup() != 0) {
162 throw SocketException(
"WSACleanup() failed");
168 const string &protocol) {
169 struct servent *serv;
171 if ((serv = getservbyname(service.c_str(), protocol.c_str())) == NULL)
172 return atoi(service.c_str());
174 return ntohs(serv->s_port);
189 sockaddr_in destAddr;
190 fillAddr(foreignAddress, foreignPort, destAddr);
193 if (::connect(sockDesc, (sockaddr *) &destAddr,
sizeof(destAddr)) < 0) {
200 if (::send(sockDesc, (
raw_type *) buffer, bufferLen, 0) < 0) {
208 if ((rtn = ::recv(sockDesc, (
raw_type *) buffer, bufferLen, 0)) < 0) {
218 unsigned int addr_len =
sizeof(addr);
220 if (getpeername(
sockDesc, (sockaddr *) &addr,(socklen_t *) &addr_len) < 0) {
221 throw SocketException(
"Fetch of foreign address failed (getpeername())",
true);
223 return inet_ntoa(addr.sin_addr);
228 unsigned int addr_len =
sizeof(addr);
230 if (getpeername(
sockDesc, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) {
231 throw SocketException(
"Fetch of foreign port failed (getpeername())",
true);
233 return ntohs(addr.sin_port);
245 connect(foreignAddress, foreignPort);
255 setLocalPort(localPort);
260 unsigned short localPort,
int queueLen)
262 setLocalAddressAndPort(localAddress, localPort);
269 throw SocketException(
"Accept failed (accept())",
true);
276 if (listen(sockDesc, queueLen) < 0) {
290 setLocalPort(localPort);
296 setLocalAddressAndPort(localAddress, localPort);
303 int broadcastPermission = 1;
304 setsockopt(
sockDesc, SOL_SOCKET, SO_BROADCAST,
305 (
raw_type *) &broadcastPermission,
sizeof(broadcastPermission));
309 sockaddr_in nullAddr;
310 memset(&nullAddr, 0,
sizeof(nullAddr));
311 nullAddr.sin_family = AF_UNSPEC;
314 if (::
connect(
sockDesc, (sockaddr *) &nullAddr,
sizeof(nullAddr)) < 0) {
316 if (errno != WSAEAFNOSUPPORT) {
318 if (errno != EAFNOSUPPORT) {
320 throw SocketException(
"Disconnect failed (connect())",
true);
326 const string &foreignAddress,
unsigned short foreignPort)
327 throw(SocketException) {
328 sockaddr_in destAddr;
329 fillAddr(foreignAddress, foreignPort, destAddr);
333 (sockaddr *) &destAddr,
sizeof(destAddr)) != bufferLen) {
334 throw SocketException(
"Send failed (sendto())",
true);
339 unsigned short &sourcePort)
throw(SocketException) {
340 sockaddr_in clntAddr;
341 socklen_t addrLen =
sizeof(clntAddr);
344 (sockaddr *) &clntAddr, (socklen_t *) &addrLen)) < 0) {
345 throw SocketException(
"Send failed (sendto())",
true);
347 sourceAddress = inet_ntoa(clntAddr.sin_addr);
348 sourcePort = ntohs(clntAddr.sin_port);
354 if (setsockopt(
sockDesc, IPPROTO_IP, IP_MULTICAST_TTL,
355 (
raw_type *) &multicastTTL,
sizeof(multicastTTL)) < 0) {
356 throw SocketException(
"Multicast TTL set failed (setsockopt())",
true);
361 struct ip_mreq multicastRequest;
363 multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str());
364 multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
365 if (setsockopt(
sockDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP,
367 sizeof(multicastRequest)) < 0) {
368 throw SocketException(
"Multicast group join failed (setsockopt())",
true);
373 struct ip_mreq multicastRequest;
375 multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str());
376 multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
377 if (setsockopt(
sockDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP,
379 sizeof(multicastRequest)) < 0) {
380 throw SocketException(
"Multicast group leave failed (setsockopt())",
true);
const char * what() const
void send(const void *buffer, int bufferLen)
void setMulticastTTL(unsigned char multicastTTL)
CommunicatingSocket(int type, int protocol)
void connect(const string &foreignAddress, unsigned short foreignPort)
void setLocalPort(unsigned short localPort)
static void fillAddr(const string &address, unsigned short port, sockaddr_in &addr)
string getForeignAddress()
static unsigned short resolveService(const string &service, const string &protocol="tcp")
void joinGroup(const string &multicastGroup)
unsigned short getForeignPort()
int recvFrom(void *buffer, int bufferLen, string &sourceAddress, unsigned short &sourcePort)
void leaveGroup(const string &multicastGroup)
void setLocalAddressAndPort(const string &localAddress, unsigned short localPort=0)
void setListen(int queueLen)
TCPServerSocket(unsigned short localPort, int queueLen=5)
void sendTo(const void *buffer, int bufferLen, const string &foreignAddress, unsigned short foreignPort)
SocketException(const string &message, bool inclSysMsg=false)
unsigned short getLocalPort()
int recv(void *buffer, int bufferLen)
Socket(const Socket &sock)