Changeset 5 in libcf++
- Timestamp:
- 03/21/15 19:54:07 (10 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/cf/network.h
r4 r5 20 20 { 21 21 /** 22 * network host 23 */ 24 class host 25 { 26 private: 27 std::string mAddress; 28 cf::uint16_t mPort; 29 30 public: 31 /** 32 * constructor 33 * @param address host address 34 * @param port port number 35 */ 36 host(const std::string & address = "", 37 const cf::uint16_t port = 0); 38 39 /** 40 * get host address 41 * @return host address 42 */ 43 std::string address() const; 44 45 /** 46 * get port number 47 * @return port number 48 */ 49 cf::uint16_t port() const; 50 51 /** 52 * is empty ? 53 * @return true; false 54 */ 55 cf::bool_t empty() const; 56 }; 57 58 /** 22 59 * TCP Socket 23 60 */ … … 27 64 cf::socket_t mSocket; 28 65 cf::int32_t mTimeout; 29 std::string mHost;30 cf::uint16_t mPort;31 66 32 67 /** … … 35 70 * @throw cf::exception 36 71 */ 37 cf::void_t receive(bin & out) 72 cf::void_t receive(bin & out) const 38 73 throw (cf::exception); 39 74 … … 58 93 59 94 /** 60 * connect to host:port 61 * @param host host 62 * @param port port 95 * connect to address:port 96 * @param peer peer host 63 97 * @param timeout timeout 64 98 * @throw cf::exception 65 99 */ 66 cf::void_t connect(const cf::char_t * host, 67 const cf::uint16_t port, 100 cf::void_t connect(const host & peer, 68 101 const cf::int32_t timeout = 0) 69 102 throw (cf::exception); … … 76 109 */ 77 110 cf::void_t listen(const cf::uint16_t port, 78 const cf::int32_t backlog = 5) 111 const cf::int32_t backlog = 5) const 79 112 throw (cf::exception); 80 113 … … 84 117 * @throw cf::exception 85 118 */ 86 tcp accept() 119 tcp accept() const 87 120 throw (cf::exception); 88 121 … … 108 141 * @throw cf::exception 109 142 */ 110 cf::void_t send(const bin & in) 143 cf::void_t send(const bin & in) const 111 144 throw (cf::exception); 112 145 … … 117 150 * @throw cf::exception 118 151 */ 119 bin receive(const cf::int32_t size) 152 bin receive(const cf::int32_t size) const 120 153 throw (cf::exception); 121 154 … … 125 158 * @throw cf::exception 126 159 */ 127 bin receive() 160 bin receive() const 128 161 throw (cf::exception); 129 162 … … 133 166 cf::void_t getOption(const cf::int32_t optname, 134 167 cf::void_t * optval, 135 cf::int32_t * optlen) 168 cf::int32_t * optlen) const 136 169 throw (cf::exception); 137 170 … … 141 174 cf::void_t setOption(const cf::int32_t optname, 142 175 const cf::void_t * optval, 143 const cf::int32_t optlen) 144 throw (cf::exception); 145 146 /** 147 * set non-blocking 148 * @param flag true; false 149 * @see setTimeout 150 */ 151 cf::void_t setNonBlocking(const cf::bool_t flag); 176 const cf::int32_t optlen) const 177 throw (cf::exception); 152 178 153 179 /** … … 157 183 */ 158 184 cf::void_t setTimeout(const cf::int32_t seconds); 185 186 /** 187 * get local host 188 * @return local host 189 * @see cf::network::host 190 */ 191 host local() const 192 throw (cf::exception); 193 194 /** 195 * get peer host 196 * @return peer host 197 * @see cf::network::host 198 */ 199 host peer() const 200 throw (cf::exception); 159 201 }; 160 202 -
trunk/src/network.cpp
r4 r5 37 37 #endif 38 38 39 #define ALLOW_SOCKET_TIME_WAIT 40 41 cf::socket_t gInvalidSocket = -1; 39 #define INVALID_SOCKET -1 42 40 43 41 /*--------------------------------------------------------------*/ … … 48 46 long GetMACAddress(cf::char_t *addr); 49 47 48 static std::string convertAddressToString(struct sockaddr_in & addr) 49 { 50 cf::uint8_t * bytes = NULL; 51 cf::char_t str[32] = {0x00}; 52 53 bytes = reinterpret_cast<cf::uint8_t *>(&addr.sin_addr.s_addr); 54 snprintf(str, sizeof(str) - 1, "%u.%u.%u.%u", bytes[0], 55 bytes[1], 56 bytes[2], 57 bytes[3]); 58 59 return str; 60 } 61 62 static cf::void_t setNonBlocking(const cf::socket_t sock, 63 const cf::bool_t flag) 64 { 65 #ifdef _ON_WINDOWS 66 cf::ulong_t mode = flag ? 1 : 0; 67 ioctlsocket(sock, FIONBIO, &mode); 68 #else 69 cf::int32_t mode = fcntl(sock, F_GETFL, 0); 70 71 if (flag) mode |= O_NONBLOCK; 72 else mode &= ~O_NONBLOCK; 73 74 fcntl(sock, F_SETFL, mode); 75 #endif 76 } 77 50 78 static cf::void_t waitForTimeout(const cf::socket_t sock, 51 79 const cf::int32_t timeout, … … 87 115 } 88 116 89 static cf::void_t setLinger(cf::network::tcp & tcp) 90 throw (cf::exception) 91 { 92 #ifdef ALLOW_SOCKET_TIME_WAIT 93 return; 94 #else 117 static cf::void_t setReuseAddress(const cf::network::tcp & tcp) 118 throw (cf::exception) 119 { 95 120 try 96 121 { 97 struct linger linger; 98 99 linger.l_onoff = 1; 100 linger.l_linger = 0; 101 102 tcp.setOption(SO_LINGER, &linger, sizeof(linger)); 122 cf::int32_t reuseaddr = 1; 123 124 tcp.setOption(SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)); 103 125 } 104 126 catch (cf::exception & e) … … 106 128 FORWARD_EXCEPTION(e); 107 129 } 108 #endif 109 } 110 111 static cf::void_t setReuseAddress(cf::network::tcp & tcp) 112 throw (cf::exception) 113 { 114 try 115 { 116 cf::int32_t reuseaddr = 1; 117 118 tcp.setOption(SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)); 119 } 120 catch (cf::exception & e) 121 { 122 FORWARD_EXCEPTION(e); 123 } 130 } 131 132 typedef cf::int32_t (*getSocketNameAPI)(cf::socket_t sock, 133 struct sockaddr * addr, 134 socklen_t *len); 135 136 static cf::network::host getSocketNameFromFunction(const cf::socket_t sock, 137 getSocketNameAPI api) 138 throw (cf::exception) 139 { 140 cf::int32_t result = 0; 141 struct sockaddr_in addr; 142 socklen_t len = sizeof(struct sockaddr_in); 143 144 result = api(sock, (struct sockaddr *)&addr, &len); 145 if (result < 0) 146 THROW_EXCEPTION("cannot get sockket or peer name (" 147 << cf::exception::systemCode() 148 << ")"); 149 150 return cf::network::host(convertAddressToString(addr), addr.sin_port); 124 151 } 125 152 /*--------------------------------------------------------------*/ 153 154 cf::network::host::host(const std::string & address, 155 const cf::uint16_t port) 156 : mAddress(address), 157 mPort(port) 158 { 159 } 160 161 std::string cf::network::host::address() const 162 { 163 return mAddress; 164 } 165 166 cf::uint16_t cf::network::host::port() const 167 { 168 return mPort; 169 } 170 171 cf::bool_t cf::network::host::empty() const 172 { 173 return (address().empty() || port() <= 0) ? true : false; 174 } 126 175 127 176 cf::network::tcp::tcp(const cf::socket_t attachedSocket) … … 145 194 } 146 195 147 if (mSocket == gInvalidSocket)196 if (mSocket == INVALID_SOCKET) 148 197 mSocket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 149 198 … … 159 208 cf::void_t cf::network::tcp::close() 160 209 { 161 if (mSocket == gInvalidSocket)210 if (mSocket == INVALID_SOCKET) 162 211 return; 163 212 164 213 closesocket(mSocket); 165 214 166 mSocket = gInvalidSocket; 167 mHost = ""; 168 mPort = 0; 169 } 170 171 cf::void_t cf::network::tcp::connect(const cf::char_t * host, 172 const cf::uint16_t port, 215 mSocket = INVALID_SOCKET; 216 } 217 218 cf::void_t cf::network::tcp::connect(const cf::network::host & peer, 173 219 const cf::int32_t timeout) 174 220 throw (cf::exception) 175 221 { 176 if ( !host || !port)222 if (peer.empty()) 177 223 THROW_EXCEPTION("invalid host info"); 178 224 … … 183 229 struct hostent * hostEnt; 184 230 231 const cf::char_t * host = peer.address().c_str(); 232 cf::uint16_t port = peer.port(); 233 185 234 /* 1. set data */ 186 235 addr.sin_family = AF_INET; … … 204 253 try 205 254 { 206 setLinger(*this);207 255 setReuseAddress(*this); 208 256 } … … 212 260 } 213 261 214 if (timeout > 0) 215 setNonBlocking(true); 262 setTimeout(timeout); 216 263 217 264 /* 4. connect */ … … 243 290 } 244 291 } 245 246 /* set */247 mHost = host;248 mPort = port;249 mTimeout = timeout;250 292 } 251 293 252 294 cf::void_t cf::network::tcp::listen(const cf::uint16_t port, 253 const cf::int32_t backlog) 295 const cf::int32_t backlog) const 254 296 throw (cf::exception) 255 297 { … … 268 310 try 269 311 { 270 setLinger(*this);271 312 setReuseAddress(*this); 272 313 } … … 285 326 } 286 327 287 cf::network::tcp cf::network::tcp::accept() 328 cf::network::tcp cf::network::tcp::accept() const 288 329 throw (cf::exception) 289 330 { … … 302 343 throw (exception) 303 344 { 304 if (sock == gInvalidSocket)345 if (sock == INVALID_SOCKET) 305 346 THROW_EXCEPTION("has invalid socket"); 306 347 … … 313 354 throw (exception) 314 355 { 315 if (mSocket == gInvalidSocket)356 if (mSocket == INVALID_SOCKET) 316 357 THROW_EXCEPTION("has invalid socket"); 317 358 318 359 cf::socket_t sock = mSocket; 319 360 320 mSocket = gInvalidSocket;361 mSocket = INVALID_SOCKET; 321 362 322 363 return sock; 323 364 } 324 365 325 cf::void_t cf::network::tcp::send(const cf::bin & in) 366 cf::void_t cf::network::tcp::send(const cf::bin & in) const 326 367 throw (cf::exception) 327 368 { … … 337 378 } 338 379 339 cf::void_t cf::network::tcp::receive(cf::bin & out) 380 cf::void_t cf::network::tcp::receive(cf::bin & out) const 340 381 throw (cf::exception) 341 382 { … … 364 405 } 365 406 366 cf::bin cf::network::tcp::receive(const cf::int32_t size) 407 cf::bin cf::network::tcp::receive(const cf::int32_t size) const 367 408 throw (cf::exception) 368 409 { … … 375 416 } 376 417 377 cf::bin cf::network::tcp::receive() 418 cf::bin cf::network::tcp::receive() const 378 419 throw (cf::exception) 379 420 { … … 396 437 cf::void_t cf::network::tcp::getOption(const cf::int32_t optname, 397 438 cf::void_t * optval, 398 cf::int32_t * optlen) 439 cf::int32_t * optlen) const 399 440 throw (cf::exception) 400 441 { … … 416 457 cf::void_t cf::network::tcp::setOption(const cf::int32_t optname, 417 458 const cf::void_t * optval, 418 const cf::int32_t optlen) 459 const cf::int32_t optlen) const 419 460 throw (cf::exception) 420 461 { … … 434 475 } 435 476 436 cf::void_t cf::network::tcp::setNonBlocking(const cf::bool_t flag)437 {438 #ifdef _ON_WINDOWS439 cf::ulong_t mode = flag ? 1 : 0;440 ioctlsocket(mSocket, FIONBIO, &mode);441 #else442 cf::int32_t mode = fcntl(mSocket, F_GETFL, 0);443 444 if (flag) mode |= O_NONBLOCK;445 else mode &= ~O_NONBLOCK;446 447 fcntl(mSocket, F_SETFL, mode);448 #endif449 }450 451 477 cf::void_t cf::network::tcp::setTimeout(const cf::int32_t seconds) 452 478 { 479 setNonBlocking(mSocket, seconds > 0 /*? true : false*/); 453 480 mTimeout = seconds; 481 } 482 483 cf::network::host cf::network::tcp::peer() const 484 throw (cf::exception) 485 { 486 try 487 { 488 return getSocketNameFromFunction(mSocket, getpeername); 489 } 490 catch (cf::exception & e) 491 { 492 FORWARD_EXCEPTION(e); 493 } 494 } 495 496 cf::network::host cf::network::tcp::local() const 497 throw (cf::exception) 498 { 499 try 500 { 501 return getSocketNameFromFunction(mSocket, getsockname); 502 } 503 catch (cf::exception & e) 504 { 505 FORWARD_EXCEPTION(e); 506 } 454 507 } 455 508 -
trunk/test/test.cpp
r4 r5 213 213 { 214 214 client.attach(server.accept().detach()); 215 cf::network::host peer = client.peer(); 216 std::cout << "client <" 217 << peer.address() << ":" << peer.port() 218 << "> is connected" 219 << std::endl; 215 220 msg = client.receive(); 216 221 client.send(msg); … … 237 242 { 238 243 cf::network::tcp client; 244 cf::network::host host(HOST, PORT); 245 239 246 cf::ulong_t tid = cf::task::thread::id(); 240 247 cf::bin msg(STR(STRING << " " << tid).c_str()); 241 248 cf::bin response; 242 249 243 client.connect( HOST, PORT, TIMEOUT);250 client.connect(host, TIMEOUT); 244 251 client.send(msg); 245 252 response = client.receive();
Note:
See TracChangeset
for help on using the changeset viewer.