~
[scx.git] / include / Socket.hpp
blob08cc7c2e586a74d8213cd0b29dcd7eb733135075
1 #ifndef SCX_SOCKET_HPP
2 #define SCX_SOCKET_HPP
4 #include <sys/socket.h>
5 #include <netinet/in.h>
6 #include <arpa/inet.h>
7 #include <strings.h>
9 #include <string>
11 namespace scx {
13 struct SocketOpt
15 bool reuseAddr;
16 bool reusePort;
17 bool keepAlive;
19 SocketOpt():
20 reuseAddr(true),
21 reusePort(true),
22 keepAlive(true) {}
25 class UdpSocket;
26 class TcpSocket;
28 class InetAddr
30 friend class UdpSocket;
31 friend class TcpSocket;
33 public:
34 InetAddr():
35 mAddrLen(sizeof(sockaddr_in))
37 bzero(&mAddr, sizeof(mAddr));
38 mAddr.sin_family = AF_INET;
41 InetAddr(const std::string& ip, int port):
42 mAddrLen(sizeof(sockaddr_in))
44 bzero(&mAddr, sizeof(mAddr));
45 mAddr.sin_family = AF_INET;
46 inet_pton(AF_INET, ip.c_str(), &mAddr.sin_addr);
47 mAddr.sin_port = htons(port);
50 explicit InetAddr(int port):
51 mAddrLen(sizeof(sockaddr_in))
53 bzero(&mAddr, sizeof(mAddr));
54 mAddr.sin_family = AF_INET;
55 mAddr.sin_addr.s_addr = htonl(INADDR_ANY);
56 mAddr.sin_port = htons(port);
59 void Assign(const std::string& ip, int port)
61 inet_pton(AF_INET, ip.c_str(), &mAddr.sin_addr);
62 mAddr.sin_port = htons(port);
65 void Assign(int port)
67 mAddr.sin_addr.s_addr = htonl(INADDR_ANY);
68 mAddr.sin_port = htons(port);
71 std::string GetIp() const
73 char buf[INET_ADDRSTRLEN];
74 const char* p = inet_ntop(AF_INET, &mAddr.sin_addr, buf, sizeof(buf));
75 return p != NULL ? std::string(p) : "";
78 int GetPort() const
80 return ntohs(mAddr.sin_port);
83 private:
84 sockaddr_in mAddr;
85 socklen_t mAddrLen;
88 #define SCX_SOCKET_COPY_SOCKET_COMMON(ClassName) \
89 public:\
90 ~ClassName() \
91 { \
92 if (mFd != -1) \
93 close(mFd); \
94 } \
96 int GetFd() const \
97 { \
98 return mFd; \
99 } \
101 InetAddr& GetAddr() \
103 return mInetAddr; \
106 void SetOption(const SocketOpt& opt) { \
107 int ret; \
108 int on; \
109 on = opt.reuseAddr; \
110 ret = setsockopt(mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); \
111 on = opt.reusePort; \
112 ret = setsockopt(mFd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)); \
113 on = opt.keepAlive; \
114 ret = setsockopt(mFd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); \
117 int Bind(const std::string& ip, int port) { \
118 mInetAddr.Assign(ip, port); \
119 return bind(mFd, (sockaddr*)&mInetAddr.mAddr, mInetAddr.mAddrLen); \
122 int Bind(int port) { \
123 mInetAddr.Assign(port); \
124 return bind(mFd, (sockaddr*)&mInetAddr.mAddr, mInetAddr.mAddrLen); \
127 int Bind(const InetAddr& addr) { \
128 mInetAddr = addr; \
129 return bind(mFd, (sockaddr*)&mInetAddr.mAddr, mInetAddr.mAddrLen); \
132 private:\
133 int mFd; \
134 InetAddr mInetAddr; \
136 class UdpSocket
138 SCX_SOCKET_COPY_SOCKET_COMMON(UdpSocket);
140 public:
141 UdpSocket()
143 mFd = socket(AF_INET, SOCK_DGRAM, 0);
146 ssize_t RecvFrom(void* buf, size_t len, InetAddr& iadr, int flags = 0)
148 return recvfrom(mFd, buf, len, flags, (sockaddr*)&iadr.mAddr, &iadr.mAddrLen);
151 ssize_t SendTo(const void* buf, size_t len, InetAddr& iadr, int flags = 0) const
153 return sendto(mFd, buf, len, flags, (sockaddr*)&iadr.mAddr, iadr.mAddrLen);
158 class TcpSocket
160 SCX_SOCKET_COPY_SOCKET_COMMON(TcpSocket);
162 public:
163 TcpSocket()
165 mFd = socket(AF_INET, SOCK_STREAM, 0);
168 int Listen(int backlog) const
170 return listen(mFd, backlog);
173 void Accept(TcpSocket& clientSocket) const
175 InetAddr& clientAddr = clientSocket.GetAddr();
176 int connFd = accept(mFd, (sockaddr*)&clientAddr.mAddr, &clientAddr.mAddrLen);
177 clientSocket.mFd = connFd;
180 int Connect(const InetAddr& iadr) const
182 return connect(mFd, (sockaddr*)&iadr.mAddr, iadr.mAddrLen);
185 ssize_t Recv(void* buf, size_t len, int flags = 0) const
187 return recv(mFd, buf, len, flags);
190 ssize_t Send(const void* buf, size_t len, int flags = 0) const
192 return send(mFd, buf, len, flags);
196 #undef SCX_SOCKET_COPY_SOCKET_COMMON
198 class UnixSocket
205 #endif