00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "stdafx.h"
00037 #include "Socket.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "Array_ptr.h"
00041
00042 #include <memory>
00043
00044 #ifdef _MEMORY_DEBUG
00045 #define new DEBUG_NEW
00046 #define malloc DEBUG_MALLOC
00047 static char THIS_FILE[] = __FILE__;
00048 #endif
00049
00050 KOMODIA_NAMESPACE_START
00051
00052 #define CSocket_LOGNAME "CSocket"
00053
00054 CSocket::CSocket(BOOL bRawSocket) : CSocketBase(),
00055 m_bRaw(bRawSocket)
00056 {
00057 try
00058 {
00059
00060 SetName(CSocket_LOGNAME);
00061
00062
00063 InitializeIP();
00064 }
00065 ERROR_HANDLER("CSocket")
00066 }
00067
00068 CSocket::CSocket(SOCKET aSocket) : CSocketBase()
00069 {
00070
00071 if (aSocket!=INVALID_SOCKET)
00072 ReportError("CSocket","Received invalid socket!");
00073 else
00074 try
00075 {
00076
00077 SetName(CSocket_LOGNAME);
00078
00079
00080 InitializeIP();
00081
00082
00083 AssignSocket(aSocket);
00084 }
00085 ERROR_HANDLER("CSocket")
00086 }
00087
00088 CSocket::~CSocket()
00089 {
00090 try
00091 {
00092
00093 Close();
00094 }
00095 ERROR_HANDLER("~CSocket")
00096 }
00097
00098 BOOL CSocket::Create(int iProtocol)
00099 {
00100
00101 if (ValidSocket())
00102 Close();
00103
00104 try
00105 {
00106
00107 if (!m_bOverlapped)
00108 {
00109
00110 if (m_bRaw || iProtocol==IPPROTO_ICMP)
00111 m_aSocket=socket(AF_INET,
00112 SOCK_RAW,
00113 iProtocol);
00114 else
00115 if (iProtocol==IPPROTO_TCP)
00116 m_aSocket=socket(AF_INET,
00117 SOCK_STREAM,
00118 iProtocol);
00119 else if (iProtocol==IPPROTO_UDP)
00120 m_aSocket=socket(AF_INET,
00121 SOCK_DGRAM,
00122 iProtocol);
00123 }
00124 else
00125 {
00126
00127 if (m_bRaw || iProtocol==IPPROTO_ICMP)
00128 m_aSocket=WSASocket(AF_INET,
00129 SOCK_RAW,
00130 iProtocol,
00131 NULL,
00132 NULL,
00133 WSA_FLAG_OVERLAPPED);
00134 else
00135 if (iProtocol==IPPROTO_TCP)
00136 m_aSocket=WSASocket(AF_INET,
00137 SOCK_STREAM,
00138 iProtocol,
00139 NULL,
00140 NULL,
00141 WSA_FLAG_OVERLAPPED);
00142 else if (iProtocol==IPPROTO_UDP)
00143 m_aSocket=WSASocket(AF_INET,
00144 SOCK_DGRAM,
00145 iProtocol,
00146 NULL,
00147 NULL,
00148 WSA_FLAG_OVERLAPPED);
00149 }
00150
00151
00152 if (m_aSocket==INVALID_SOCKET)
00153 {
00154
00155 SetLastError("Create");
00156
00157
00158 return FALSE;
00159 }
00160
00161 if (m_bRaw)
00162 {
00163
00164 unsigned int iTrue=1;
00165
00166 if(setsockopt(m_aSocket,
00167 IPPROTO_IP,
00168 IP_HDRINCL,
00169 (char*)&iTrue,
00170 sizeof(iTrue))==GetErrorCode())
00171 {
00172
00173 SetLastError("Create");
00174
00175
00176 return FALSE;
00177 }
00178 }
00179
00180
00181 return TRUE;
00182 }
00183 ERROR_HANDLER_RETURN("Create",FALSE)
00184 }
00185
00186 void CSocket::SetProtocol(unsigned char ucProtocol)
00187 {
00188 m_ucProtocol=ucProtocol;
00189 }
00190
00191 int CSocket::Send(IP aDestinationAddress,
00192 const char* pBuffer,
00193 unsigned long ulBufferLength,
00194 unsigned short usDestinationPort)
00195 {
00196 try
00197 {
00198
00199 if (!CheckSocketValid())
00200 return GetErrorCode();
00201
00202
00203 if (ulBufferLength &&
00204 !pBuffer)
00205 return GetErrorCode();
00206
00207
00208 sockaddr_in aTargetAddress;
00209 memset(&aTargetAddress,
00210 0,
00211 sizeof(aTargetAddress));
00212
00213 aTargetAddress.sin_family=AF_INET;
00214 aTargetAddress.sin_addr.s_addr=aDestinationAddress;
00215 aTargetAddress.sin_port=htons(usDestinationPort);
00216
00217
00218 int iResult;
00219
00220
00221 iResult=!GetErrorCode();
00222
00223
00224 if (iResult!=GetErrorCode())
00225
00226 iResult=sendto(GetHandle(),
00227 (const char*)pBuffer,
00228 ulBufferLength,
00229 0,
00230 (sockaddr*)&aTargetAddress,
00231 sizeof(aTargetAddress));
00232
00233
00234 if (iResult==GetErrorCode() &&
00235 GetSystemLastError()!=WSAEWOULDBLOCK)
00236
00237 SetLastError("Send");
00238
00239
00240 return iResult;
00241 }
00242 ERROR_HANDLER_RETURN("Send",GetErrorCode())
00243 }
00244
00245 int CSocket::Send(const std::string& rDestinationAddress,
00246 const char* pBuffer,
00247 unsigned long ulBufferLength,
00248 unsigned short usDestinationPort)
00249 {
00250 try
00251 {
00252
00253 if (!CheckSocketValid())
00254 return GetErrorCode();
00255
00256 return Send(inet_addr(rDestinationAddress.c_str()),
00257 pBuffer,
00258 ulBufferLength,
00259 usDestinationPort);
00260 }
00261 ERROR_HANDLER_RETURN("Send",GetErrorCode())
00262 }
00263
00264 BOOL CSocket::ValidSocket() const
00265 {
00266 return m_aSocket!=INVALID_SOCKET;
00267 }
00268
00269 BOOL CSocket::Bind(IP aSourceAddress,
00270 unsigned short usPort)
00271 {
00272 try
00273 {
00274
00275 if (!CheckSocketValid())
00276 return FALSE;
00277
00278
00279 sockaddr_in soSrc;
00280
00281
00282 memset(&soSrc,0,sizeof(soSrc));
00283 soSrc.sin_family=AF_INET;
00284
00285
00286 if (aSourceAddress)
00287 soSrc.sin_addr.s_addr=aSourceAddress;
00288 else
00289 soSrc.sin_addr.s_addr=ADDR_ANY ;
00290
00291 soSrc.sin_port=htons(usPort);
00292
00293
00294 if (bind(GetHandle(),
00295 (sockaddr*)&soSrc,
00296 sizeof(soSrc)))
00297 {
00298
00299 SetLastError("Bind");
00300
00301
00302 return FALSE;
00303 }
00304 else
00305
00306 m_aConnectedTo=soSrc;
00307
00308
00309 if (aSourceAddress &&
00310 !m_ulSourceAddress)
00311 m_ulSourceAddress=aSourceAddress;
00312
00313 return TRUE;
00314 }
00315 ERROR_HANDLER_RETURN("Bind",FALSE)
00316 }
00317
00318 BOOL CSocket::Bind(const std::string& rSourceAddress,
00319 unsigned short usPort)
00320 {
00321 try
00322 {
00323
00324 if (!CheckSocketValid())
00325 return FALSE;
00326
00327 if (rSourceAddress.empty())
00328 return Bind((IP)0,
00329 usPort);
00330 else
00331 return Bind(inet_addr(rSourceAddress.c_str()),
00332 usPort);
00333 }
00334 ERROR_HANDLER_RETURN("Bind",FALSE)
00335 }
00336
00337 unsigned short CSocket::GetBindPort()const
00338 {
00339 try
00340 {
00341
00342 if (!CheckSocketValid())
00343 return FALSE;
00344
00345
00346 sockaddr_in soSrc;
00347
00348
00349 int iSize;
00350 iSize=sizeof(soSrc);
00351
00352
00353 if (getsockname(GetHandle(),
00354 (sockaddr*)&soSrc,
00355 &iSize))
00356 {
00357
00358 SetLastError("Bind");
00359
00360
00361 return 0;
00362 }
00363 else
00364 return htons(soSrc.sin_port);
00365 }
00366 ERROR_HANDLER_RETURN("GetBindPort",0)
00367 }
00368
00369 SOCKET CSocket::GetHandle()const
00370 {
00371 return m_aSocket;
00372 }
00373
00374 SOCKET CSocket::Detach()
00375 {
00376
00377 SOCKET aTmp;
00378 aTmp=m_aSocket;
00379
00380
00381 m_aSocket=INVALID_SOCKET;
00382
00383
00384 return aTmp;
00385 }
00386
00387 BOOL CSocket::CheckSocketValid()const
00388 {
00389 try
00390 {
00391
00392 if (!ValidSocket())
00393 {
00394
00395 ReportError("CheckSocketValid","Operation made on non existant socket!");
00396
00397
00398 return FALSE;
00399 }
00400
00401
00402 return TRUE;
00403 }
00404 ERROR_HANDLER_RETURN("CheckSocketValid",FALSE)
00405 }
00406
00407 BOOL CSocket::Close()
00408 {
00409 try
00410 {
00411
00412
00413 if (!ValidSocket())
00414 return FALSE;
00415
00416
00417 if (closesocket(GetHandle())==GetErrorCode())
00418 {
00419
00420 SetLastError("Close");
00421
00422
00423 return FALSE;
00424 }
00425
00426
00427 m_aSocket=INVALID_SOCKET;
00428
00429
00430 return TRUE;
00431 }
00432 ERROR_HANDLER_RETURN("Close",FALSE)
00433 }
00434
00435 void CSocket::SetSourceAddress(IP aSourceAddress)
00436 {
00437 m_ulSourceAddress=aSourceAddress;
00438 }
00439
00440 void CSocket::SetSourceAddress(const std::string& rSourceAddress)
00441 {
00442 try
00443 {
00444
00445 if (rSourceAddress.empty())
00446 m_ulSourceAddress=0;
00447 else
00448 m_ulSourceAddress=inet_addr(rSourceAddress.c_str());
00449 }
00450 ERROR_HANDLER("SetSourceAddress")
00451 }
00452
00453 void CSocket::SetTTL(unsigned char ucTTL)
00454 {
00455 try
00456 {
00457
00458 if (!CheckSocketValid())
00459 return;
00460
00461 if(setsockopt(GetHandle(),
00462 IPPROTO_IP,
00463 IP_TTL,
00464 (const char*)&ucTTL,
00465 sizeof(ucTTL)))
00466 SetLastError("SetTTL");
00467 }
00468 ERROR_HANDLER("SetTTL")
00469 }
00470
00471 BOOL CSocket::IsRaw() const
00472 {
00473 return m_bRaw;
00474 }
00475
00476 void CSocket::InitializeIP()
00477 {
00478 try
00479 {
00480
00481 m_aSocket=INVALID_SOCKET;
00482
00483
00484 m_ulSourceAddress=0;
00485
00486
00487 m_ucTTL=64;
00488
00489
00490 m_bOverlapped=FALSE;
00491
00492
00493 memset(&m_aConnectedTo,
00494 0,
00495 sizeof(m_aConnectedTo));
00496 }
00497 ERROR_HANDLER("InitializeIP")
00498 }
00499
00500 void CSocket::AssignSocket(SOCKET aNewSocket,
00501 unsigned char ucProtocol)
00502 {
00503 try
00504 {
00505
00506 m_ucProtocol=ucProtocol;
00507
00508
00509 m_aSocket=aNewSocket;
00510 }
00511 ERROR_HANDLER("AssignSocket")
00512 }
00513
00514 int CSocket::ReceiveFrom(char* pBuffer,
00515 unsigned long ulBufferLength,
00516 IP& rIP,
00517 unsigned short& rSourcePort)
00518 {
00519 try
00520 {
00521 if (!ValidSocket() ||
00522 !pBuffer ||
00523 !ulBufferLength)
00524 return GetErrorCode();
00525
00526
00527 int iResult;
00528
00529
00530 if (m_ucProtocol!=IPPROTO_TCP)
00531 {
00532
00533 sockaddr saConnected;
00534
00535 int iTmp;
00536 iTmp=sizeof(saConnected);
00537
00538
00539 iResult=recvfrom(GetHandle(),
00540 pBuffer,
00541 ulBufferLength,
00542 NULL,
00543 &saConnected,
00544 &iTmp);
00545
00546
00547 if (iResult!=GetErrorCode())
00548 {
00549
00550 rIP=((sockaddr_in*)&saConnected)->sin_addr.S_un.S_addr;
00551
00552
00553 rSourcePort=htons(((sockaddr_in*)&saConnected)->sin_port);
00554
00555
00556 return iResult;
00557 }
00558 else
00559 {
00560
00561 SetLastError("Receive");
00562
00563
00564 rIP=0;
00565 rSourcePort=0;
00566
00567
00568 return iResult;
00569 }
00570 }
00571 else
00572 {
00573
00574 ReportError("Receive","Can't run on TCP socket!");
00575
00576
00577 return GetErrorCode();
00578 }
00579 }
00580 ERROR_HANDLER_RETURN("Receive",GetErrorCode())
00581 }
00582
00583 int CSocket::LocalReceive(char* pBuffer,
00584 unsigned long ulBufferLength,
00585 BOOL bPeek)
00586 {
00587 try
00588 {
00589 if (!ValidSocket() ||
00590 !pBuffer ||
00591 !ulBufferLength)
00592 return GetErrorCode();
00593
00594
00595 int iFlag;
00596 if (bPeek)
00597 iFlag=MSG_PEEK;
00598 else
00599 iFlag=NULL;
00600
00601
00602 int iResult;
00603
00604
00605 if (m_ucProtocol!=IPPROTO_TCP)
00606 {
00607
00608 sockaddr saConnected;
00609
00610 int iTmp;
00611 iTmp=sizeof(saConnected);
00612
00613
00614 iResult=recvfrom(GetHandle(),
00615 pBuffer,
00616 ulBufferLength,
00617 iFlag,
00618 &saConnected,
00619 &iTmp);
00620
00621
00622 if (iResult!=GetErrorCode())
00623
00624 memcpy(&m_aConnectedTo,
00625 &saConnected,
00626 sizeof(saConnected));
00627 }
00628 else
00629
00630
00631 iResult=recv(GetHandle(),
00632 pBuffer,
00633 ulBufferLength,
00634 iFlag);
00635
00636
00637 if (iResult==GetErrorCode() &&
00638 GetSystemLastError()!=WSAEWOULDBLOCK)
00639
00640 if (!bPeek)
00641
00642 SetLastError("Receive");
00643 else
00644
00645 SetLastError("Peek");
00646
00647
00648 return iResult;
00649 }
00650 ERROR_HANDLER_RETURN("LocalReceive",GetErrorCode())
00651 }
00652
00653 int CSocket::Receive(char *pBuffer,
00654 unsigned long ulBufferLength)
00655 {
00656 try
00657 {
00658 return LocalReceive(pBuffer,
00659 ulBufferLength,
00660 FALSE);
00661 }
00662 ERROR_HANDLER_RETURN("Receive",GetErrorCode())
00663 }
00664
00665 int CSocket::Peek(char* pBuffer,
00666 unsigned long ulBufferLength)
00667 {
00668 try
00669 {
00670 return LocalReceive(pBuffer,
00671 ulBufferLength,
00672 TRUE);
00673 }
00674 ERROR_HANDLER_RETURN("Peek",GetErrorCode())
00675 }
00676
00677 long CSocket::GetPeerAddress() const
00678 {
00679
00680 return m_aConnectedTo.sin_addr.S_un.S_addr;
00681 }
00682
00683 BOOL CSocket::Shutdown(SocketShutdown eHow)
00684 {
00685 if (!CheckSocketValid())
00686 return FALSE;
00687
00688 try
00689 {
00690 int iHow;
00691
00692
00693 if (eHow==ssReceive)
00694 iHow=SD_RECEIVE;
00695 else if (eHow==ssSend)
00696 iHow=SD_SEND;
00697 else
00698 iHow=SD_BOTH;
00699
00700
00701 if (shutdown(GetHandle(),iHow))
00702 {
00703
00704 SetLastError("Shutdown");
00705
00706
00707 return FALSE;
00708 }
00709
00710
00711 return TRUE;
00712 }
00713 ERROR_HANDLER_RETURN("Shutdown",FALSE)
00714 }
00715
00716 unsigned short CSocket::GetPeerPort() const
00717 {
00718 return htons(m_aConnectedTo.sin_port);
00719 }
00720
00721 BOOL CSocket::CanRead()const
00722 {
00723 try
00724 {
00725
00726 if (!CheckSocketValid())
00727 return FALSE;
00728
00729
00730 fd_set aDescriptor;
00731 FD_ZERO(&aDescriptor);
00732
00733
00734 FD_SET(GetHandle(),
00735 &aDescriptor);
00736
00737
00738 timeval aTime;
00739 aTime.tv_sec=0;
00740 aTime.tv_usec=0;
00741
00742
00743 int iRetVal;
00744 iRetVal=select(NULL,
00745 &aDescriptor,
00746 NULL,
00747 NULL,
00748 &aTime);
00749
00750
00751 if (iRetVal==GetErrorCode())
00752 {
00753
00754 SetLastError("CanRead");
00755
00756
00757 return FALSE;
00758 }
00759 else
00760
00761 return FD_ISSET(GetHandle(),
00762 &aDescriptor);
00763 }
00764 ERROR_HANDLER_RETURN("CanRead",FALSE)
00765 }
00766
00767 BOOL CSocket::CanWrite()const
00768 {
00769 try
00770 {
00771
00772 if (!CheckSocketValid())
00773 return FALSE;
00774
00775
00776 fd_set aDescriptor;
00777 FD_ZERO(&aDescriptor);
00778
00779
00780 FD_SET(GetHandle(),
00781 &aDescriptor);
00782
00783
00784 timeval aTime;
00785 aTime.tv_sec=0;
00786 aTime.tv_usec=0;
00787
00788
00789 int iRetVal;
00790 iRetVal=select(NULL,
00791 NULL,
00792 &aDescriptor,
00793 NULL,
00794 &aTime);
00795
00796
00797 if (iRetVal==GetErrorCode())
00798 {
00799
00800 SetLastError("CanWrite");
00801
00802
00803 return FALSE;
00804 }
00805 else
00806
00807 return FD_ISSET(GetHandle(),
00808 &aDescriptor);
00809 }
00810 ERROR_HANDLER_RETURN("CanWrite",FALSE)
00811 }
00812
00813 BOOL CSocket::IsCreated()const
00814 {
00815 return ValidSocket();
00816 }
00817
00818 BOOL CSocket::SetBroadcast(BOOL bBroadcast)
00819 {
00820 try
00821 {
00822
00823 if (!CheckSocketValid())
00824 return FALSE;
00825
00826
00827 if(setsockopt(GetHandle(),
00828 SOL_SOCKET,
00829 SO_BROADCAST,
00830 (char*)&bBroadcast,
00831 sizeof(bBroadcast))==GetErrorCode())
00832 {
00833
00834 SetLastError("SetBroadcast");
00835
00836
00837 return FALSE;
00838 }
00839
00840 return TRUE;
00841 }
00842 ERROR_HANDLER_RETURN("SetBroadcast",FALSE)
00843 }
00844
00845 unsigned char CSocket::GetTTL()const
00846 {
00847 return m_ucTTL;
00848 }
00849
00850 IP CSocket::GetSourceAddress()const
00851 {
00852 return m_ulSourceAddress;
00853 }
00854
00855 unsigned char CSocket::GetProtocol()const
00856 {
00857 return m_ucProtocol;
00858 }
00859
00860 BOOL CSocket::SetReceiveTimeout(unsigned long ulMS)
00861 {
00862 try
00863 {
00864
00865 if (!CheckSocketValid())
00866 return FALSE;
00867
00868
00869 if(setsockopt(GetHandle(),
00870 SOL_SOCKET,
00871 SO_RCVTIMEO,
00872 (char*)&ulMS,
00873 sizeof(ulMS))==GetErrorCode())
00874 {
00875
00876 SetLastError("SetReceiveTimeout");
00877
00878
00879 return FALSE;
00880 }
00881 else
00882 return TRUE;
00883 }
00884 ERROR_HANDLER_RETURN("SetReceiveTimeout",FALSE)
00885 }
00886
00887 bool CSocket::operator==(const CSocket& rSocket)const
00888 {
00889 return m_aSocket==rSocket.m_aSocket;
00890 }
00891
00892 bool CSocket::operator<(const CSocket& rSocket)const
00893 {
00894 return m_aSocket<rSocket.m_aSocket;
00895 }
00896
00897 void CSocket::SetConnectedTo(const sockaddr_in& rAddress)
00898 {
00899 m_aConnectedTo=rAddress;
00900 }
00901
00902 IP CSocket::GetBindAddress()const
00903 {
00904 return m_ulSourceAddress;
00905 }
00906
00907 KOMODIA_NAMESPACE_END
00908