00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #if defined(_WIN32) || defined(_WIN64)
00018 #include <spl/configwin32.h>
00019 #include <stdio.h>
00020 #else
00021 #include <spl/autoconf/config.h>
00022 #endif
00023
00024
00025 #include <spl/threading/Thread.h>
00026
00027 #ifdef HAVE_SYS_IOCTL_H
00028 #include <sys/ioctl.h>
00029 #endif
00030
00031 #include <spl/Environment.h>
00032 #include <ctype.h>
00033 #include <spl/Debug.h>
00034 #include <spl/Exception.h>
00035 #include <spl/Log.h>
00036 #include <spl/net/ServerSocket.h>
00037 #include <spl/net/Socket.h>
00038 #include <spl/io/SocketStream.h>
00039 #include <spl/net/TcpSocket.h>
00040
00041 bool Socket::m_inited = false;
00042
00043 void Socket::sinit()
00044 {
00045 #ifdef _WINDOWS
00046 m_inited = true;
00047 WORD wVersionRequested;
00048 WSADATA wsaData;
00049 int err;
00050
00051 wVersionRequested = MAKEWORD( 2, 2 );
00052
00053 err = WSAStartup( wVersionRequested, &wsaData );
00054 if ( err != 0 )
00055 {
00056 throw new SocketException(Environment::LastErrorMessage());
00057 }
00058 #endif
00059 }
00060
00061 void Socket::Init()
00062 {
00063 if ( ! m_inited )
00064 {
00065 sinit();
00066 }
00067 m_saAddr.sin_family = AF_INET;
00068 m_saAddr.sin_port = htons(0);
00069 m_saAddr.sin_addr.s_addr = htonl(0);
00070 m_errorStatus = 0;
00071 m_closed = false;
00072 }
00073
00074 Socket::Socket(const Socket& sock)
00075 : m_saAddr(sock.m_saAddr),
00076 m_fd(sock.m_fd),
00077 m_closed(sock.m_closed),
00078 m_errorStatus(sock.m_errorStatus)
00079 {
00080 }
00081
00082 Socket& Socket::operator =(const Socket& sock)
00083 {
00084 m_saAddr = sock.m_saAddr;
00085 m_fd = sock.m_fd;
00086 m_closed = sock.m_closed;
00087 m_errorStatus = sock.m_errorStatus;
00088
00089 return *this;
00090 }
00091
00092 Socket::Socket()
00093 : m_fd()
00094 {
00095 Init();
00096 }
00097
00098 Socket::Socket(SOCKET fd, bool dummy)
00099 {
00100 Init();
00101 m_fd = fd;
00102 }
00103
00109 Socket::Socket ( int port, int family, int streamType, int protocol )
00110 {
00111 Init();
00112 m_fd = ::socket(family, streamType, protocol);
00113 if (m_fd < 0)
00114 {
00115 throw new SocketException(Environment::LastErrorMessage());
00116 }
00117 m_saAddr.sin_port = htons(port);
00118 }
00119
00120 Socket::Socket (int port)
00121 {
00122 Init();
00123 m_fd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00124 if (m_fd < 0)
00125 {
00126 throw new SocketException(Environment::LastErrorMessage());
00127 }
00128 m_saAddr.sin_port = htons(port);
00129 }
00130
00131 TcpSocketPtr ServerSocket::Accept()
00132 {
00133 if ( ! m_sock.m_inited )
00134 {
00135 m_sock.sinit();
00136 }
00137 SOCKET fd;
00138 SOCKADDR_IN saAddr;
00139 #ifdef _WINDOWS
00140 int size = sizeof(saAddr);
00141 #else
00142 socklen_t size = sizeof(saAddr);
00143 #endif
00144 m_sock.m_errorStatus = 0;
00145 fd = ::accept(m_sock.m_fd, (struct sockaddr *)&saAddr, &size);
00146 if ( fd == INVALID_SOCKET )
00147 {
00148 if (m_sock.IsClosed())
00149 {
00150 return TcpSocketPtr();
00151 }
00152 #ifdef _WINDOWS
00153 m_sock.m_errorStatus = WSAGetLastError();
00154 if ( 10004 == m_sock.m_errorStatus )
00155 {
00156 return Accept();
00157 }
00158 #else
00159 m_sock.m_errorStatus = errno;
00160 #endif
00161 throw new SocketException(Environment::LastErrorMessage());
00162 }
00163 TcpSocketPtr sock = TcpSocketPtr( new TcpSocket(fd) );
00164 memcpy(&sock->m_sock->m_saAddr, &saAddr, sizeof(saAddr));
00165
00166
00167
00168 return sock;
00169 }
00170
00171 Socket::~Socket()
00172 {
00173 if (m_fd > 0)
00174 {
00175 Close ();
00176 }
00177 }
00178
00179 void Socket::SetNonBlocking()
00180 {
00181 #ifdef _WINDOWS
00182 u_long arg = 1;
00183 if (ioctlsocket(m_fd, FIONBIO, &arg) != 0)
00184 {
00185 throw new SocketException(Environment::LastErrorMessage());
00186 }
00187 #else
00188 int flags;
00189
00190 if ((flags = fcntl(m_fd, F_GETFL, 0)) < 0 ||
00191 fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) < 0)
00192 {
00193 throw new SocketException(Environment::LastErrorMessage());
00194 }
00195 #endif
00196 }
00197
00198 void Socket::SetBlocking()
00199 {
00200 #ifdef _WINDOWS
00201 u_long arg = 0;
00202 if (ioctlsocket(m_fd, FIONBIO, &arg) != 0)
00203 {
00204 throw new SocketException(Environment::LastErrorMessage());
00205 }
00206 #else
00207 int flags;
00208
00209 if ((flags = fcntl(m_fd, F_GETFL, 0)) < 0 ||
00210 fcntl(m_fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
00211 {
00212 throw new SocketException(Environment::LastErrorMessage());
00213 }
00214 #endif
00215 }
00216
00217 void ServerSocket::Bind ()
00218 {
00219 m_sock.m_saAddr.sin_addr.s_addr = htonl (INADDR_ANY);
00220
00221 if (::bind (m_sock.m_fd, (struct sockaddr *)&m_sock.m_saAddr, sizeof (m_sock.m_saAddr)) != 0)
00222 {
00223 m_sock.m_errorStatus = Environment::LastError();
00224 throw new SocketException(Environment::LastErrorMessage());
00225 }
00226 }
00227
00228 void Socket::SetNoDelay()
00229 {
00230 #ifdef _WINDOWS
00231 BOOL opt = TRUE;
00232 if (setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&opt, sizeof(BOOL)) != 0)
00233 #else
00234 int opt = 1;
00235 if (setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(int)) != 0)
00236 #endif
00237 {
00238 throw new SocketException(Environment::LastErrorMessage());
00239 }
00240 }
00241
00242 void Socket::SetSendTimeout(int toMS)
00243 {
00244 int ret = setsockopt(m_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&toMS, sizeof(int));
00245 #ifdef _WINDOWS
00246 if ( ret != NO_ERROR )
00247 #else
00248 if ( ret < 0 )
00249 #endif
00250 {
00251 throw new SocketException(Environment::LastErrorMessage());
00252 }
00253 }
00254
00255 void Socket::SetRecvTimeout(int toMS)
00256 {
00257 int len = sizeof(int);
00258 int ret = setsockopt(m_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&toMS, sizeof(int));
00259 #ifdef _WIN32
00260 if ( ret != NO_ERROR )
00261 #else
00262 if ( ret < 0 )
00263 #endif
00264 {
00265 throw new SocketException(Environment::LastErrorMessage());
00266 }
00267 }
00268
00269 int Socket::GetSendTimeout()
00270 {
00271 int timeout;
00272 #ifdef _WIN32
00273 int len = sizeof(int);
00274 #else
00275 socklen_t len = sizeof(socklen_t);
00276 #endif
00277 int ret = getsockopt(m_fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, &len);
00278 #ifdef _WIN32
00279 if ( ret != NO_ERROR )
00280 #else
00281 if ( ret < 0 )
00282 #endif
00283 {
00284 throw new SocketException(Environment::LastErrorMessage());
00285 }
00286 return timeout;
00287 }
00288
00289 int Socket::GetRecvTimeout()
00290 {
00291 int timeout;
00292 #ifdef _WIN32
00293 int len = sizeof(int);
00294 #else
00295 socklen_t len = sizeof(socklen_t);
00296 #endif
00297 int ret = getsockopt(m_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, &len);
00298 #ifdef _WIN32
00299 if ( ret != NO_ERROR )
00300 #else
00301 if ( ret < 0 )
00302 #endif
00303 {
00304 throw new SocketException(Environment::LastErrorMessage());
00305 }
00306 return timeout;
00307 }
00308
00309 void Socket::Flush()
00310 {
00311 #ifdef _WIN32
00312 int ret = WSAIoctl(m_fd, SIO_FLUSH, NULL, 0, NULL, 0, NULL, NULL, NULL);
00313 if ( ret != 0 )
00314 {
00315 #ifdef _WIN32
00316 m_errorStatus = WSAGetLastError();
00317 #else
00318 m_errorStatus = errno;
00319 #endif
00320 throw new SocketException(Environment::LastErrorMessage());
00321 }
00322 #endif
00323 }
00324
00325 void Socket::SetAddrReuse (int i)
00326 {
00327 m_errorStatus = setsockopt (m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(int));
00328 if(m_errorStatus != 0)
00329 {
00330 throw new SocketException(Environment::LastErrorMessage());
00331 }
00332 }
00333
00334 void Socket::SetLingerOn ()
00335 {
00336 struct linger l;
00337
00338 l.l_onoff = 1;
00339 l.l_linger = 5;
00340 if (setsockopt (m_fd, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(struct linger)) != 0)
00341 {
00342 throw new SocketException(Environment::LastErrorMessage());
00343 }
00344 }
00345
00346 void Socket::SetLingerOff ()
00347 {
00348 struct linger l;
00349
00350 l.l_onoff = 0;
00351 l.l_linger = 0;
00352 if (setsockopt (m_fd, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(struct linger)) != 0)
00353 {
00354 throw new SocketException(Environment::LastErrorMessage());
00355 }
00356 }
00357
00358 void Socket::Send (const Array<byte>& data, const int offset, const int len)
00359 {
00360 ASSERT(offset + len <= data.Length());
00361
00362 if (::send (m_fd, &(((const char *)data.Data())[offset]), len, 0) < 0)
00363 {
00364 #ifdef _WIN32
00365 int err = WSAGetLastError();
00366 #else
00367 int err = errno;
00368 #endif
00369 m_errorStatus = err;
00370 throw new SocketException(Environment::LastErrorMessage());
00371 }
00372 }
00373
00374 int Socket::Recv (Array<byte>& buf, const int offset, const int blen)
00375 {
00376 ASSERT(offset + blen <= buf.Length());
00377
00378 int count = ::recv (m_fd, &(((char *)buf.Data())[offset]), blen, 0);
00379 #ifdef _WIN32
00380 if ( SOCKET_ERROR == count )
00381 #else
00382 if ( 0 > count )
00383 #endif
00384 {
00385 #ifdef _WIN32
00386 int err = WSAGetLastError();
00387 #else
00388 int err = errno;
00389 #endif
00390 m_errorStatus = err;
00391 throw new SocketException(Environment::LastErrorMessage());
00392 }
00393 return count;
00394 }
00395
00396 int Socket::RecvByte()
00397 {
00398 int b = 0;
00399 int count = ::recv (m_fd, (char *)&b, 1, 0);
00400 #ifdef _WIN32
00401 if ( SOCKET_ERROR == count )
00402 #else
00403 if ( 0 > count )
00404 #endif
00405 {
00406 #ifdef _WIN32
00407 int err = WSAGetLastError();
00408 #else
00409 int err = errno;
00410 #endif
00411 m_errorStatus = err;
00412 throw new SocketException(Environment::LastErrorMessage());
00413 }
00414 return b;
00415 }
00416
00417 void ServerSocket::Listen (int iNumBuf)
00418 {
00419 if (::listen(m_sock.m_fd, iNumBuf) != 0)
00420 {
00421 #ifdef _WIN32
00422 int error = WSAGetLastError();
00423 #else
00424 int error = errno;
00425 #endif
00426 throw new SocketException(Environment::LastErrorMessage());
00427 }
00428 }
00429
00430 int Socket::GetBytesAvail( )
00431 {
00432 #ifdef _WIN32
00433 u_long arg = 0;
00434 if (ioctlsocket(m_fd, FIONREAD, &arg) == 0)
00435 {
00436 return (int)arg;
00437 }
00438 else
00439 {
00440 m_errorStatus = WSAGetLastError();
00441 throw new SocketException(Environment::LastErrorMessage());
00442 }
00443 #else
00444 int arg = 0;
00445 if ( ioctl(m_fd, FIONREAD, &arg) != 0 )
00446 {
00447 m_errorStatus = errno;
00448 throw new SocketException(Environment::LastErrorMessage());
00449 }
00450 return arg;
00451 #endif
00452 }
00453
00454 String Socket::GetRemoteIp( )
00455 {
00456 SOCKADDR_IN name;
00457 char buf[17];
00458
00459 #ifdef _WIN32
00460 int namelen = sizeof(name);
00461 #else
00462 socklen_t namelen = sizeof(name);
00463 #endif
00464 if (0 != getpeername( m_fd, (struct sockaddr *)&name, &namelen ))
00465 {
00466 throw new SocketException(Environment::LastErrorMessage());
00467 }
00468 #ifdef _WIN32
00469 sprintf(buf, "%hd.%hd.%hd.%hd", (short)name.sin_addr.S_un.S_un_b.s_b1, (short)name.sin_addr.S_un.S_un_b.s_b2, (short)name.sin_addr.S_un.S_un_b.s_b3, (short)name.sin_addr.S_un.S_un_b.s_b4);
00470 #else
00471 strcpy(buf, inet_ntoa(name.sin_addr));
00472 #endif
00473 return String(buf);
00474 }
00475
00476 bool Socket::IsClosed()
00477 {
00478
00479
00480 if ( m_closed )
00481 {
00482 return true;
00483 }
00484 char buf;
00485 int count = recv(m_fd, &buf, 1, MSG_PEEK);
00486 if ( 0 > count )
00487 {
00488 m_closed = true;
00489 return true;
00490 }
00491
00492 return false;
00493 }
00494
00495 void Socket::Shutdown( int i )
00496 {
00497 m_closed = true;
00498 if ( 0 != ::shutdown(m_fd, i) )
00499 {
00500 #ifdef _WIN32
00501 int error = WSAGetLastError();
00502 #else
00503 int error = errno;
00504 #endif
00505 m_errorStatus = error;
00506 throw new SocketException(Environment::LastErrorMessage());
00507 }
00508 }
00509
00510 void Socket::ShutdownService()
00511 {
00512 #ifdef _WIN32
00513 WSACleanup();
00514 #endif
00515 }
00516
00517 #if defined(DEBUG) || defined(_DEBUG)
00518 void Socket::CheckMem() const
00519 {
00520 }
00521
00522 void Socket::ValidateMem() const
00523 {
00524 }
00525 #endif
00526
00527
00528 ServerSocket::ServerSocket( int port, int numbuf )
00529 : m_sock(port)
00530 {
00531 Bind();
00532 Listen( numbuf );
00533 }
00534
00535 ServerSocket::~ServerSocket()
00536 {
00537 }
00538
00539 SocketStream::SocketStream(SocketPtr sock)
00540 : m_sock(sock)
00541 {
00542 }
00543
00544 SocketStream::~SocketStream()
00545 {
00546 Close();
00547 }
00548
00549 void SocketStream::Close()
00550 {
00551 m_sock->Close();
00552 }
00553
00554 void SocketStream::Flush()
00555 {
00556 m_sock->Flush();
00557 }
00558
00559 int SocketStream::Read(Array<byte>& buffer, const int offset, int count)
00560 {
00561 return m_sock->Recv(buffer, offset, count);
00562 }
00563
00564 int SocketStream::ReadByte()
00565 {
00566 return m_sock->RecvByte();
00567 }
00568
00569 long SocketStream::Seek(const long offset, const SeekOrigin origin)
00570 {
00571 throw new NotImplementedException();
00572 }
00573
00574 void SocketStream::Write(const Array<byte>& buffer, const int offset, const int count)
00575 {
00576 m_sock->Send(buffer, offset, count);
00577 }
00578
00579 void SocketStream::WriteByte(byte value)
00580 {
00581 Array<byte> buf(1);
00582 buf[0] = value;
00583 m_sock->Send(buf);
00584 }
00585
00586 bool SocketStream::CanRead() const
00587 {
00588 return true;
00589 }
00590
00591 bool SocketStream::CanSeek() const
00592 {
00593 return false;
00594 }
00595
00596 bool SocketStream::CanWrite() const
00597 {
00598 return true;
00599 }
00600
00601 long SocketStream::Length() const
00602 {
00603 return m_sock->GetBytesAvail();
00604 }
00605
00606 long SocketStream::Position() const
00607 {
00608 return 0;
00609 }
00610
00611 #ifdef DEBUG
00612 void SocketStream::ValidateMem() const
00613 {
00614 m_sock.ValidateMem();
00615 }
00616
00617 void SocketStream::CheckMem() const
00618 {
00619 m_sock.CheckMem();
00620 }
00621 #endif
00622
00623 TcpSocket::TcpSocket( SOCKET fd )
00624 : m_sock(new Socket(fd, false)), m_address("")
00625 {
00626 m_strm = SocketStreamPtr(new SocketStream(m_sock));
00627 }
00628
00629 TcpSocket::TcpSocket( const String& address, int port )
00630 : m_sock(new Socket(port)), m_address(address)
00631 {
00632 m_strm = SocketStreamPtr(new SocketStream(m_sock));
00633 }
00634
00635 TcpSocket::~TcpSocket()
00636 {
00637 m_sock->Close();
00638 }
00639
00640 spl::IStreamPtr TcpSocket::GetStream()
00641 {
00642 return m_strm;
00643 }
00644
00648 void TcpSocket::Connect ()
00649 {
00650
00651
00652
00653 if (isdigit(m_address.CharAt(0)))
00654 {
00655 m_sock->m_saAddr.sin_addr.s_addr = inet_addr(m_address.GetChars());
00656 }
00657 else
00658 {
00659 hostent *phostent = gethostbyname(m_address.GetChars());
00660 memcpy ((char *)&(m_sock->m_saAddr.sin_addr), phostent->h_addr, phostent->h_length);
00661 }
00662 if (::connect (m_sock->m_fd, (struct sockaddr *)&m_sock->m_saAddr, sizeof (SOCKADDR_IN)) != 0)
00663 {
00664 m_sock->m_errorStatus = Environment::LastError();
00665 throw new SocketException(Environment::LastErrorMessage());
00666 }
00667 }
00668
00669 #if defined(DEBUG) || defined(_DEBUG)
00670 void TcpSocket::CheckMem() const
00671 {
00672 m_strm.CheckMem();
00673 m_address.CheckMem();
00674 m_sock.CheckMem();
00675 }
00676
00677 void TcpSocket::ValidateMem() const
00678 {
00679 m_strm.ValidateMem();
00680 m_address.ValidateMem();
00681 m_sock.ValidateMem();
00682 }
00683 #endif