]>
Dogcows Code - chaz/yoink/blob - src/Moof/Socket.hh
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
12 #ifndef _MOOF_SOCKET_HH_
13 #define _MOOF_SOCKET_HH_
25 #include <arpa/inet.h>
27 #include <sys/socket.h>
28 #include <sys/types.h>
32 #include <sys/ioctl.h>
36 #include <Moof/Log.hh>
37 #include <Moof/Packet.hh>
38 #include <Moof/Thread.hh>
42 #define SO_NONBLOCK 1024
57 mAddress
.sa
.sa_family
= AF_UNSPEC
;
58 mAddress
.v4
.sin_port
= 0;
61 SocketAddress(const std::string
& service
, const std::string
& name
,
62 int type
= SOCK_STREAM
, int family
= AF_UNSPEC
)
64 init(service
, name
, type
, family
);
67 SocketAddress(const std::string
& service
,
68 int type
= SOCK_STREAM
, int family
= AF_UNSPEC
)
70 init(service
, type
, family
);
73 SocketAddress(const struct addrinfo
* addr
, const std::string
& name
)
75 mType
= addr
->ai_socktype
;
76 memcpy(&mAddress
.sa
, addr
->ai_addr
, addr
->ai_addrlen
);
78 mSize
= addr
->ai_addrlen
;
81 SocketAddress(const struct sockaddr
* addr
, size_t size
,
82 int type
= SOCK_STREAM
)
85 memcpy(&mAddress
.sa
, addr
, size
);
91 static SocketAddress
broadcast(const std::string
& service
)
93 std::istringstream
stream(service
);
97 struct sockaddr_in addr
;
98 addr
.sin_family
= AF_INET
;
99 addr
.sin_port
= htons(port
);
100 addr
.sin_addr
.s_addr
= INADDR_BROADCAST
;
101 memset(&addr
.sin_zero
, 0, sizeof(addr
.sin_zero
));
102 return SocketAddress((sockaddr
*)&addr
, sizeof(addr
), SOCK_DGRAM
);
106 void init(const std::string
& service
, const std::string
& name
= "",
107 int type
= SOCK_STREAM
, int family
= AF_UNSPEC
)
109 ASSERT(type
== SOCK_STREAM
|| type
== SOCK_DGRAM
);
110 ASSERT(family
== AF_INET
|| family
== AF_INET6
|| family
== AF_UNSPEC
);
112 struct addrinfo hints
;
113 memset(&hints
, 0, sizeof(hints
));
114 hints
.ai_family
= family
;
115 hints
.ai_socktype
= type
;
116 hints
.ai_flags
= AI_PASSIVE
;
118 struct addrinfo
* addr
;
119 int status
= getaddrinfo(name
.length() > 0 ? name
.c_str() : 0,
120 service
.c_str(), &hints
, &addr
);
123 mType
= addr
->ai_socktype
;
124 memcpy(&mAddress
.sa
, addr
->ai_addr
, addr
->ai_addrlen
);
125 mSize
= addr
->ai_addrlen
;
127 if (name
!= "") mName
= name
;
128 else setNameFromAddress();
134 Mf::logWarning(gai_strerror(status
));
137 mAddress
.sa
.sa_family
= AF_UNSPEC
;
138 mAddress
.v4
.sin_port
= 0;
142 void init(const std::string
& service
,
143 int type
= SOCK_STREAM
, int family
= AF_UNSPEC
)
145 init(service
, "", type
, family
);
149 const std::string
& name() const
154 void setName(const std::string
& name
)
159 unsigned short port() const
161 return ntohs(mAddress
.v4
.sin_port
);
171 return mAddress
.sa
.sa_family
;
175 const struct sockaddr
* address() const
177 return mSize
!= 0 ? &mAddress
.sa
: 0;
186 static int resolve(const std::string
& service
, const std::string
& name
,
187 int type
, int family
, std::vector
<SocketAddress
>& resolved
)
189 ASSERT(type
== SOCK_STREAM
|| type
== SOCK_DGRAM
);
190 ASSERT(family
== AF_INET
|| family
== AF_INET6
|| family
== AF_UNSPEC
);
194 struct addrinfo hints
;
195 memset(&hints
, 0, sizeof(hints
));
196 hints
.ai_family
= family
;
197 hints
.ai_socktype
= type
;
198 hints
.ai_flags
= AI_PASSIVE
;
200 struct addrinfo
* list
;
201 int status
= getaddrinfo(name
.length() > 0 ? name
.c_str() : 0,
202 service
.length() > 0 ? service
.c_str() : 0, &hints
, &list
);
205 for (struct addrinfo
* addr
= list
;
206 addr
!= 0; addr
= addr
->ai_next
)
208 resolved
.push_back(SocketAddress(addr
, name
));
215 Mf::logWarning(gai_strerror(status
));
224 void setNameFromAddress()
227 // inet_ntop was introduced in Vista
228 mName
= inet_ntoa(mAddress
.v4
.sin_addr
);
230 char name
[INET6_ADDRSTRLEN
] = {'\0'};
231 inet_ntop(mAddress
.sa
.sa_family
, &mAddress
.sa
, name
, sizeof(name
));
242 sockaddr_storage storage
;
254 Socket(const SocketAddress
& address
) :
258 mFd
= socket(address
.family(), address
.type(), 0);
264 if (mFd
!= -1) closesocket(mFd
);
266 if (mFd
!= -1) close(mFd
);
271 bool isConnected() const
276 const SocketAddress
& address() const
284 return ::connect(mFd
, mAddress
.address(), mAddress
.size());
289 return ::bind(mFd
, mAddress
.address(), mAddress
.size());
292 int listen(int backlog
= SOMAXCONN
)
294 return ::listen(mFd
, backlog
> 0 ? backlog
: SOMAXCONN
);
303 int set(int option
, int value
= 0)
305 if (option
== SO_NONBLOCK
)
308 int flags
= fcntl(mFd
, F_GETFL
);
309 return fcntl(mFd
, F_SETFL
, (value
? O_NONBLOCK
: 0) | flags
);
311 return ioctl(mFd
, FIONBIO
, value
);
314 return setsockopt(mFd
, SOL_SOCKET
, option
, &value
, sizeof(value
));
317 int set(int option
, const std::string
& value
)
319 return setsockopt(mFd
, SOL_SOCKET
, option
,
320 value
.c_str(), value
.length());
323 int get(int option
, int& value
)
325 if (option
== SO_NONBLOCK
)
328 int flags
= fcntl(mFd
, F_GETFL
);
329 return flags
& O_NONBLOCK
;
331 return ioctl(mFd
, FIONBIO
, &value
);
334 socklen_t optlen
= sizeof(value
);
335 return getsockopt(mFd
, SOL_SOCKET
, option
, &value
, &optlen
);
338 int get(int option
, std::string
& value
)
340 char str
[64] = {'\0'};
341 socklen_t optlen
= sizeof(str
);
342 int result
= getsockopt(mFd
, SOL_SOCKET
, option
, &str
, &optlen
);
347 void write(const Packet
& packet
)
349 write(mAddress
, packet
);
352 void write(const SocketAddress
& address
, const Packet
& packet
)
354 sendto(mFd
, packet
.bytes(), packet
.size(), 0,
355 address
.address(), address
.size());
361 int size
= recv(mFd
, buffer
, sizeof(buffer
), 0);
363 return Packet(buffer
, size
);
366 Packet
read(SocketAddress
& address
)
371 sockaddr_storage storage
;
373 socklen_t length
= sizeof(addr
);
376 int size
= recvfrom(mFd
, buffer
, sizeof(buffer
), 0,
379 address
= SocketAddress(&addr
.sa
, length
, mAddress
.type());
380 return Packet(buffer
, size
);
388 // for accepting a socket from fd
392 sockaddr_storage storage
;
394 socklen_t length
= sizeof(addr
);
396 mFd
= ::accept(fd
, &addr
.sa
, &length
);
397 mAddress
= SocketAddress(&addr
.sa
, length
);
402 SocketAddress mAddress
;
406 class ResolverTask
: public ThreadedTask
410 ResolverTask(const std::string
& service
, const std::string
& name
,
411 int type
= SOCK_STREAM
, int family
= AF_UNSPEC
) :
414 mFunction
= boost::bind(&ResolverTask::resolve
,
415 this, service
, name
, type
, family
);
426 if (!mThread
) mThread
= Mf::detachFunction(mFunction
);
430 const std::vector
<SocketAddress
>& addresses() const
438 int resolve(const std::string
& service
, const std::string
& name
,
439 int type
, int family
)
441 int status
= SocketAddress::resolve(service
, name
,
442 type
, family
, mAddressList
);
448 std::vector
<SocketAddress
> mAddressList
;
456 #endif // _MOOF_SOCKET_HH_
This page took 0.053454 seconds and 5 git commands to generate.