iutest  1.17.1.0
iutest_socket.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_SOCKET_HPP_77654A63_0A08_43CA_950E_61232690163B_
16 #define INCG_IRIS_IUTEST_SOCKET_HPP_77654A63_0A08_43CA_950E_61232690163B_
17 
18 //======================================================================
19 // include
20 #include "iutest_internal_defs.hpp"
21 #include "iutest_stream.hpp"
22 
23 #ifdef IUTEST_HAS_SOCKET
24 
25 #ifdef IUTEST_OS_WINDOWS
26 # include <winsock2.h>
27 # include <ws2tcpip.h>
28 #else
29 # include <arpa/inet.h>
30 # include <netdb.h>
31 #endif
32 
33 #if defined(_MSC_VER)
34 # if defined(IUTEST_OS_WINDOWS_MOBILE)
35 # pragma comment(lib, "ws2.lib")
36 # else
37 # pragma comment(lib, "ws2_32.lib")
38 # endif
39 #endif
40 
41 namespace iutest {
42 namespace detail
43 {
44 
45 //======================================================================
46 // class
50 class BasicSocket
51 {
52 public:
53 #ifdef IUTEST_OS_WINDOWS
54  typedef SOCKET descriptor_t;
55  typedef int length_t;
56 
57 #if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
58  static const descriptor_t INVALID_DESCRIPTOR = INVALID_SOCKET;
59 #else
60  enum { INVALID_DESCRIPTOR = INVALID_SOCKET };
61 #endif
62 
63 #else
64  typedef int descriptor_t;
65  typedef size_t length_t;
66 
67 #if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
68  static const descriptor_t INVALID_DESCRIPTOR = -1;
69 #else
70  enum { INVALID_DESCRIPTOR = -1 };
71 #endif
72 
73 #endif
74 public:
75  BasicSocket() : m_socket(INVALID_DESCRIPTOR)
76  {
77 #ifdef IUTEST_OS_WINDOWS
78  WSADATA wsaData;
79  (void)WSAStartup(MAKEWORD(2, 2), &wsaData);
80 #endif
81  }
82  ~BasicSocket(void)
83  {
84  Close();
85 #ifdef IUTEST_OS_WINDOWS
86  WSACleanup();
87 #endif
88  }
89 public:
90  bool Open(const char* host, const char* port)
91  {
92  if( m_socket != INVALID_DESCRIPTOR )
93  {
94  return true;
95  }
96  addrinfo* servinfo = NULL;
97  addrinfo hints;
98  memset(&hints, 0, sizeof(hints));
99  hints.ai_family = AF_UNSPEC;
100  hints.ai_socktype = SOCK_STREAM;
101  const int err_no = getaddrinfo(host, port, &hints, &servinfo);
102  if( err_no != 0 )
103  {
104  return false;
105  }
106 
107  for( addrinfo* curr=servinfo; curr != NULL; curr = curr->ai_next )
108  {
109  const descriptor_t fd = socket(curr->ai_family, curr->ai_socktype, curr->ai_protocol);
110  if( fd != INVALID_DESCRIPTOR )
111  {
112  if( connect(fd, curr->ai_addr, static_cast<length_t>(curr->ai_addrlen)) != -1 )
113  {
114  m_socket = fd;
115  break;
116  }
117  Close(fd);
118  }
119  }
120  freeaddrinfo(servinfo);
121  return (m_socket != INVALID_DESCRIPTOR);
122  }
123  void Close()
124  {
125  Close(m_socket);
126  m_socket = INVALID_DESCRIPTOR;
127  }
128  void CheckLastError()
129  {
130 #ifdef IUTEST_OS_WINDOWS
131  const int le = WSAGetLastError();
132  IUTEST_LOG_(WARNING) << "WSAGetLastError:" << le;
133 #endif
134  }
135 public:
136  static int Close(descriptor_t d)
137  {
138 #ifdef IUTEST_OS_WINDOWS
139  return closesocket(d);
140 #else
141  return close(d);
142 #endif
143  }
144 
145 public:
146  bool IsValid() const
147  {
148  return m_socket != INVALID_DESCRIPTOR;
149  }
150 protected:
151  descriptor_t m_socket;
152 
154 };
155 
159 class SocketWriter : virtual public BasicSocket
160  , public IOutStream
161 {
162 public:
163  SocketWriter() {}
164 public:
165  bool Send(const ::std::string& message)
166  {
167  return Write(message.c_str(), message.length(), 1u);
168  }
169  bool SendLn(const ::std::string& message)
170  {
171 #ifdef IUTEST_OS_WINDOWS
172  return Send(message + "\r\n");
173 #else
174  return Send(message + "\r\n");
175  //return Send(message + "\n");
176 #endif
177  }
178 public:
179  virtual bool Write(const void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
180  {
181  if( !IsValid() )
182  {
183  return false;
184  }
185  const int size_ = static_cast<int>(size);
186  for( size_t i=0; i < cnt; ++i )
187  {
188 #ifdef IUTEST_OS_WINDOWS
189  if( send(m_socket, static_cast<const char*>(buf), size_, 0) == SOCKET_ERROR )
190  {
191  CheckLastError();
192  return false;
193  }
194 #else
195  if( write(m_socket, buf, size_) == -1 )
196  {
197  return false;
198  }
199 #endif
200  }
201  return true;
202  }
203 private:
205 };
206 
207 /*
208  * @brief ソケット読み込みクラス
209 */
210 class SocketReader : virtual public BasicSocket
211 {
212 public:
213  SocketReader() {}
214 public:
215  bool Read(void* buf, size_t size)
216  {
217  if( !IsValid() )
218  {
219  return false;
220  }
221  const int size_ = static_cast<int>(size);
222 #ifdef IUTEST_OS_WINDOWS
223  if( recv(m_socket, static_cast<char*>(buf), size_, 0) == SOCKET_ERROR )
224  {
225  CheckLastError();
226  return false;
227  }
228 #else
229  if( read(m_socket, buf, size_) == -1 )
230  {
231  return false;
232  }
233 #endif
234  return true;
235  }
236 private:
238 };
239 
240 /*
241  * @brief ソケット読み込みクラス
242 */
243 class Socket : public SocketWriter, public SocketReader
244 {
245 public:
246  Socket() {}
247 };
248 
249 } // end of namespace detail
250 } // end of namespace iutest
251 
252 #endif
253 
254 #endif // INCG_IRIS_IUTEST_SOCKET_HPP_77654A63_0A08_43CA_950E_61232690163B_
iutest_internal_defs.hpp
internal definition
iutest_stream.hpp
io stream
iutest_config.hpp
iris unit test config
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
IUTEST_LOG_
#define IUTEST_LOG_(level)
ログメッセージストリーム
Definition: iutest_port.hpp:53
IUTEST_CXX_OVERRIDE
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:670
IUTEST_PP_DISALLOW_COPY_AND_ASSIGN
#define IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeName)
コピー禁止定義
Definition: iutest_pp.hpp:25