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 "TCPSocketAsync.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040
00041 #include "BlockedBuffer.h"
00042
00043 #ifdef _MEMORY_DEBUG
00044 #define new DEBUG_NEW
00045 #define malloc DEBUG_MALLOC
00046 static char THIS_FILE[] = __FILE__;
00047 #endif
00048
00049 KOMODIA_NAMESPACE_START
00050
00051 class CErrorRegister
00052 {
00053 private:
00054 CErrorRegister()
00055 {
00056 CErrorHandler::RegisterError(teConnectionTimeout,
00057 "Connection timeout");
00058 }
00059
00060 static CErrorRegister m_sInstance;
00061 };
00062
00063 CErrorRegister CErrorRegister::m_sInstance;
00064
00065 #define CTCPSocketAsync_Class "CTCPSocketAsync"
00066
00067 CTCPSocketAsync::CTCPSocketAsync(BOOL bRawSocket) : CTCPSocket(bRawSocket),
00068 CAsyncSocket(),
00069 m_bDisabledConnect(FALSE),
00070 m_ulTimeout(0),
00071 m_pLinkedSocket(NULL),
00072 m_pOverider(NULL)
00073 {
00074 try
00075 {
00076
00077 SetName(CTCPSocketAsync_Class);
00078 }
00079 ERROR_HANDLER("CTCPSocketAsync")
00080 }
00081
00082 CTCPSocketAsync::~CTCPSocketAsync()
00083 {
00084 try
00085 {
00086
00087 if (!IsDeleting())
00088
00089 Close();
00090
00091
00092
00093 if (m_pLinkedSocket)
00094 m_pLinkedSocket->DeleteSocketFromThread();
00095 }
00096 ERROR_HANDLER("~CTCPSocketAsync")
00097 }
00098
00099 BOOL CTCPSocketAsync::Connect(IP aDestinationAddress,
00100 unsigned short usDestinationPort,
00101 BOOL bDisableAsync,
00102 BOOL bForceErrorEvent)
00103 {
00104 try
00105 {
00106
00107 return Connect(0,
00108 aDestinationAddress,
00109 usDestinationPort,
00110 bDisableAsync,
00111 bForceErrorEvent);
00112 }
00113 ERROR_HANDLER_RETURN("Connect",FALSE)
00114 }
00115
00116 BOOL CTCPSocketAsync::Connect(const std::string& rDestinationAddress,
00117 unsigned short usDestinationPort,
00118 BOOL bDisableAsync,
00119 BOOL bForceErrorEvent)
00120 {
00121 try
00122 {
00123
00124 return Connect(0,
00125 rDestinationAddress,
00126 usDestinationPort,
00127 bDisableAsync,
00128 bForceErrorEvent);
00129 }
00130 ERROR_HANDLER_RETURN("Connect",FALSE)
00131 }
00132
00133 BOOL CTCPSocketAsync::LocalConnect(unsigned short usSourcePort,
00134 IP aDestinationAddress,
00135 unsigned short usDestinationPort,
00136 BOOL bDisableAsync,
00137 BOOL bForceErrorEvent)
00138 {
00139 try
00140 {
00141
00142 if (!CheckSocketValid())
00143 return FALSE;
00144
00145
00146 if (!bDisableAsync)
00147 {
00148 int iResult;
00149 iResult=InternalWSAAsyncSelect(WM_SOCKET_CONNECT,
00150 FD_CONNECT);
00151
00152 if (iResult)
00153 {
00154
00155 int iErrorCode;
00156 iErrorCode=GetSystemLastError();
00157
00158
00159 SetLastError("Connect");
00160
00161
00162 if (bForceErrorEvent)
00163 SocketConnected(iErrorCode);
00164
00165
00166 return FALSE;
00167 }
00168
00169
00170 if (m_ulTimeout &&
00171 !IsBlocking())
00172 if (!SetSystemTimeout(m_ulTimeout))
00173 {
00174
00175 ReportError("LocalConnect","Failed to set timer!");
00176
00177
00178 if (bForceErrorEvent)
00179 SocketConnected(GetErrorCode());
00180
00181
00182 return FALSE;
00183 }
00184 }
00185
00186 else if (!Block())
00187 return FALSE;
00188
00189
00190 m_bDisabledConnect=bDisableAsync;
00191
00192
00193 BOOL bResult;
00194 bResult=CTCPSocket::Connect(usSourcePort,
00195 aDestinationAddress,
00196 usDestinationPort);
00197
00198
00199 m_bDisabledConnect=FALSE;
00200
00201 if (bResult)
00202 {
00203
00204 if (!bDisableAsync &&
00205 !IsBlocking())
00206
00207 return SocketConnected(0);
00208 else
00209
00210 return SetAsync();
00211 }
00212 else if (GetSystemLastError()!=WSAEWOULDBLOCK ||
00213 bDisableAsync ||
00214 IsBlocking())
00215 {
00216 if (m_ulTimeout)
00217
00218 KillSystemTimer();
00219
00220
00221 int iErrorCode;
00222 iErrorCode=GetSystemLastError();
00223
00224
00225 SetLastError("Connect");
00226
00227
00228 if (bForceErrorEvent &&
00229 !bDisableAsync)
00230 SocketConnected(iErrorCode);
00231
00232
00233 return FALSE;
00234 }
00235 else
00236 return TRUE;
00237 }
00238 ERROR_HANDLER_RETURN("LocalConnect",FALSE)
00239 }
00240
00241 BOOL CTCPSocketAsync::Connect(unsigned short usSourcePort,
00242 IP aDestinationAddress,
00243 unsigned short usDestinationPort,
00244 BOOL bDisableAsync,
00245 BOOL bForceErrorEvent)
00246 {
00247 try
00248 {
00249
00250 if (m_pLinkedSocket)
00251
00252 return m_pLinkedSocket->Connect(usSourcePort,
00253 aDestinationAddress,
00254 usDestinationPort,
00255 bDisableAsync,
00256 bForceErrorEvent);
00257 else
00258
00259 return LocalConnect(usSourcePort,
00260 aDestinationAddress,
00261 usDestinationPort,
00262 bDisableAsync,
00263 bForceErrorEvent);
00264 }
00265 ERROR_HANDLER_RETURN("Connect",FALSE)
00266 }
00267
00268 BOOL CTCPSocketAsync::Connect(unsigned short usSourcePort,
00269 const std::string& rDestinationAddress,
00270 unsigned short usDestinationPort,
00271 BOOL bDisableAsync,
00272 BOOL bForceErrorEvent)
00273 {
00274 try
00275 {
00276
00277 if (!CheckSocketValid())
00278 return FALSE;
00279
00280
00281 return Connect(usSourcePort,
00282 StringToLong(rDestinationAddress),
00283 usDestinationPort,
00284 bDisableAsync,
00285 bForceErrorEvent);
00286 }
00287 ERROR_HANDLER_RETURN("Connect",FALSE)
00288 }
00289
00290 BOOL CTCPSocketAsync::LocalListen(unsigned long ulBackLog)
00291 {
00292 try
00293 {
00294
00295 if (!CheckSocketValid())
00296 return FALSE;
00297
00298
00299 int iResult;
00300 iResult=InternalWSAAsyncSelect(WM_SOCKET_ACCEPT,
00301 FD_ACCEPT);
00302
00303
00304 if (iResult)
00305 {
00306
00307 SetLastError("LocalListen");
00308
00309
00310 return FALSE;
00311 }
00312
00313
00314 return CTCPSocket::Listen(ulBackLog);
00315 }
00316 ERROR_HANDLER_RETURN("LocalListen",FALSE)
00317 }
00318
00319 BOOL CTCPSocketAsync::SetAsync()
00320 {
00321 try
00322 {
00323
00324 if (!CheckSocketValid())
00325 return FALSE;
00326
00327
00328 int iResult;
00329 iResult=InternalWSAAsyncSelect(WM_SOCKET_GENERAL,
00330 FD_WRITE |
00331 FD_READ |
00332 FD_CLOSE |
00333 FD_OOB);
00334
00335
00336 if (iResult)
00337 {
00338
00339 SetLastError("SetAsync");
00340
00341
00342 return FALSE;
00343 }
00344
00345
00346 return TRUE;
00347 }
00348 ERROR_HANDLER_RETURN("SetAsync",FALSE)
00349 }
00350
00351 BOOL CTCPSocketAsync::LocalSocketConnect(int iErrorCode,
00352 BOOL bNoEvent)
00353 {
00354 try
00355 {
00356 if (m_ulTimeout)
00357
00358 KillSystemTimer();
00359
00360
00361 if (!iErrorCode)
00362
00363 SetConnectionStatus(TRUE);
00364
00365
00366 return CAsyncSocket::SocketConnected(iErrorCode,
00367 bNoEvent);
00368 }
00369 ERROR_HANDLER_RETURN("LocalSocketConnect",FALSE)
00370 }
00371
00372 BOOL CTCPSocketAsync::SocketConnected(int iErrorCode,
00373 BOOL bNoEvent)
00374 {
00375 try
00376 {
00377
00378 if (m_pLinkedSocket &&
00379 !m_bCloseEventsOnly)
00380
00381 return m_pLinkedSocket->SocketConnected(iErrorCode,
00382 bNoEvent);
00383 else
00384
00385 return LocalSocketConnect(iErrorCode,
00386 bNoEvent);
00387 }
00388 ERROR_HANDLER_RETURN("SocketConnected",FALSE)
00389 }
00390
00391 BOOL CTCPSocketAsync::LocalSocketReceive(int iErrorCode,
00392 BOOL bNoEvent)
00393 {
00394 try
00395 {
00396
00397 return CAsyncSocket::SocketReceive(iErrorCode,
00398 bNoEvent);
00399 }
00400 ERROR_HANDLER_RETURN("LocalSocketReceivet",FALSE)
00401 }
00402
00403 BOOL CTCPSocketAsync::SocketReceive(int iErrorCode,
00404 BOOL bNoEvent)
00405 {
00406 try
00407 {
00408
00409 if (m_pLinkedSocket &&
00410 !m_bCloseEventsOnly)
00411
00412 return m_pLinkedSocket->SocketReceive(iErrorCode,
00413 bNoEvent);
00414 else
00415
00416 return LocalSocketReceive(iErrorCode,
00417 bNoEvent);
00418 }
00419 ERROR_HANDLER_RETURN("SocketConnected",FALSE)
00420 }
00421
00422 BOOL CTCPSocketAsync::LocalSocketAccept(int iErrorCode,
00423 BOOL bNoEvent)
00424 {
00425 try
00426 {
00427
00428 return CAsyncSocket::SocketAccept(iErrorCode,
00429 bNoEvent);
00430 }
00431 ERROR_HANDLER_RETURN("LocalSocketAccept",FALSE)
00432 }
00433
00434 BOOL CTCPSocketAsync::SocketClosed(int iErrorCode,
00435 BOOL bNoEvent)
00436 {
00437 try
00438 {
00439 if (m_pLinkedSocket &&
00440 !m_bCloseEventsOnly)
00441
00442 return m_pLinkedSocket->SocketClosed(iErrorCode,
00443 bNoEvent);
00444 else
00445
00446 return LocalSocketClose(iErrorCode,
00447 bNoEvent);
00448
00449 }
00450 ERROR_HANDLER_RETURN("SocketClosed",FALSE)
00451 }
00452
00453 BOOL CTCPSocketAsync::LocalSocketClose(int iErrorCode,
00454 BOOL bNoEvent)
00455 {
00456 try
00457 {
00458
00459 SetConnectionStatus(FALSE);
00460
00461
00462 return CAsyncSocket::SocketClosed(iErrorCode,
00463 bNoEvent);
00464 }
00465 ERROR_HANDLER_RETURN("LocalSocketClose",FALSE)
00466 }
00467
00468 void CTCPSocketAsync::Accepted()
00469 {
00470 try
00471 {
00472
00473 AddSocketToList();
00474
00475
00476 SetAsync();
00477 }
00478 ERROR_HANDLER("CTCPSocketAsync")
00479 }
00480
00481 SOCKET CTCPSocketAsync::GetAsyncHandle() const
00482 {
00483 return GetHandle();
00484 }
00485
00486 BOOL CTCPSocketAsync::Create()
00487 {
00488 try
00489 {
00490 if (!CTCPSocket::Create())
00491 return FALSE;
00492 else
00493 {
00494
00495 m_bCloseEventsOnly=FALSE;
00496
00497
00498 SocketCreated();
00499
00500
00501 AddSocketToList();
00502
00503
00504 return TRUE;
00505 }
00506 }
00507 ERROR_HANDLER_RETURN("Create",FALSE)
00508 }
00509
00510 BOOL CTCPSocketAsync::Close()
00511 {
00512 try
00513 {
00514
00515 if (!ValidSocket())
00516 return FALSE;
00517
00518
00519 if (m_pLinkedSocket &&
00520 m_bCloseEventsOnly)
00521 m_pLinkedSocket->Close();
00522
00523
00524 CAsyncSocket::SocketClosing();
00525
00526
00527 RemoveSocketFromList();
00528
00529
00530 return CTCPSocket::Close();
00531 }
00532 ERROR_HANDLER_RETURN("Close",FALSE)
00533 }
00534
00535 BOOL CTCPSocketAsync::IsAsyncClass() const
00536 {
00537 try
00538 {
00539
00540 if (IsBlocking() ||
00541 m_bDisabledConnect)
00542 return FALSE;
00543 else
00544
00545 return TRUE;
00546 }
00547 ERROR_HANDLER_RETURN("IsAsyncClass",FALSE)
00548 }
00549
00550 void CTCPSocketAsync::BeforeAccept()
00551 {
00552 try
00553 {
00554
00555 RemoveSocketFromList();
00556 }
00557 ERROR_HANDLER("BeforeAccept")
00558 }
00559
00560 BOOL CTCPSocketAsync::SendBlockedBuffer(const CBlockedBuffer::CBlockedData& rData)
00561 {
00562 try
00563 {
00564
00565 return SendNoAdd(rData.GetData(),
00566 rData.GetDataSize())!=GetErrorCode();
00567 }
00568 ERROR_HANDLER_RETURN("SendBlockedBuffer",FALSE)
00569 }
00570
00571 int CTCPSocketAsync::Send(const char *pBuffer,
00572 unsigned long ulBufferLength)
00573 {
00574 try
00575 {
00576
00577 ResetEvent();
00578
00579
00580 int iResult;
00581 iResult=SendNoAdd(pBuffer,
00582 ulBufferLength);
00583
00584
00585 if (iResult==GetErrorCode())
00586
00587 if (WSAGetLastError()==WSAEWOULDBLOCK)
00588 if (GetBlockedBuffer())
00589 {
00590
00591 GetBlockedBuffer()->AddRecord(CBlockedBuffer::CBlockedData(pBuffer,
00592 ulBufferLength));
00593
00594
00595 iResult=0;
00596 }
00597 else if (IsBlockSend())
00598
00599 if (!IsInThread())
00600 if (WaitForBlockEvent())
00601 {
00602
00603 ::SetLastError(WSAENOTCONN);
00604
00605
00606 return GetErrorCode();
00607 }
00608 else
00609
00610 return Send(pBuffer,
00611 ulBufferLength);
00612 else
00613 {
00614
00615 Sleep(10);
00616
00617
00618 if (SendNoAdd(pBuffer,
00619 ulBufferLength)==GetErrorCode())
00620
00621 if (WSAGetLastError()==WSAEWOULDBLOCK)
00622 return 0;
00623 else
00624 return GetErrorCode();
00625 }
00626
00627 else
00628 return 0;
00629 else
00630
00631 SetLastError("Send");
00632
00633
00634 return iResult;
00635 }
00636 ERROR_HANDLER_RETURN("Send",GetErrorCode())
00637 }
00638
00639 int CTCPSocketAsync::SendNoAdd(const char* pBuffer,
00640 unsigned long ulBufferLength)
00641 {
00642 try
00643 {
00644
00645 if (!CheckSocketValid())
00646 return FALSE;
00647
00648
00649 int iResult;
00650
00651
00652 iResult=send(GetHandle(),
00653 pBuffer,
00654 ulBufferLength,
00655 NULL);
00656
00657
00658 return iResult;
00659 }
00660 ERROR_HANDLER_RETURN("SendNoAdd",GetErrorCode())
00661 }
00662
00663 BOOL CTCPSocketAsync::SocketWrite(int iErrorCode)
00664 {
00665 try
00666 {
00667
00668 if (GetBlockedBuffer())
00669 GetBlockedBuffer()->SendData();
00670
00671
00672 return CAsyncSocket::SocketWrite(iErrorCode);
00673 }
00674 ERROR_HANDLER_RETURN("OnSocketWrite",TRUE)
00675 }
00676
00677 BOOL CTCPSocketAsync::SetConnectionTimeout(unsigned long ulMS)
00678 {
00679 try
00680 {
00681
00682 if (HasSystemTimer())
00683 if (!KillSystemTimer())
00684 {
00685
00686 ReportError("SetConnectionTimeout","Failed to kill previous timer!");
00687
00688
00689 return FALSE;
00690 }
00691
00692
00693 m_ulTimeout=ulMS;
00694
00695
00696 return TRUE;
00697 }
00698 ERROR_HANDLER_RETURN("SetConnectionTimeout",FALSE)
00699 }
00700
00701 unsigned long CTCPSocketAsync::GetConnectionTimeout()const
00702 {
00703 return m_ulTimeout;
00704 }
00705
00706 void CTCPSocketAsync::SystemTimeout()
00707 {
00708
00709 SocketConnected(teConnectionTimeout);
00710 }
00711
00712 int CTCPSocketAsync::Receive(char* pBuffer,
00713 unsigned long ulBufferLength)
00714 {
00715 try
00716 {
00717
00718 int iResult;
00719 if ((iResult=CTCPSocket::Receive(pBuffer,
00720 ulBufferLength))>=0)
00721 return iResult;
00722
00723 else if (GetSystemLastError()==WSAEWOULDBLOCK)
00724 return 0;
00725 else
00726 return GetErrorCode();
00727 }
00728 ERROR_HANDLER_RETURN("Receive",GetErrorCode())
00729 }
00730
00731 int CTCPSocketAsync::Peek(char* pBuffer,
00732 unsigned long ulBufferLength)
00733 {
00734 try
00735 {
00736
00737 int iResult;
00738 if ((iResult=CTCPSocket::Peek(pBuffer,
00739 ulBufferLength))>=0)
00740 return iResult;
00741
00742 else if (GetSystemLastError()==WSAEWOULDBLOCK)
00743 return 0;
00744 else
00745 return GetErrorCode();
00746 }
00747 ERROR_HANDLER_RETURN("Peek",GetErrorCode())
00748 }
00749
00750 void CTCPSocketAsync::SetLinkedSocket(CTCPSocketAsync* pSocket,
00751 CTCPSocketOverider* pOverider)
00752 {
00753 try
00754 {
00755
00756 if (m_pLinkedSocket)
00757 m_pLinkedSocket->DeleteSocketFromThread();
00758
00759
00760 m_pLinkedSocket=pSocket;
00761 m_pOverider=pOverider;
00762
00763
00764 m_bCloseEventsOnly=FALSE;
00765 }
00766 ERROR_HANDLER("SetLinkedSocket")
00767 }
00768
00769 BOOL CTCPSocketAsync::Listen(unsigned long ulBackLog)
00770 {
00771 try
00772 {
00773
00774 if (m_pLinkedSocket)
00775
00776 return m_pLinkedSocket->Listen(ulBackLog);
00777 else
00778 return LocalListen(ulBackLog);
00779 }
00780 ERROR_HANDLER_RETURN("Listen",FALSE)
00781 }
00782
00783 BOOL CTCPSocketAsync::Bind(IP aSourceAddress,
00784 unsigned short usPort)
00785 {
00786 try
00787 {
00788
00789 if (m_pLinkedSocket)
00790
00791 return m_pLinkedSocket->Bind(aSourceAddress,
00792 usPort);
00793 else
00794 return LocalBind(aSourceAddress,
00795 usPort);
00796 }
00797 ERROR_HANDLER_RETURN("Listen",FALSE)
00798 }
00799
00800 BOOL CTCPSocketAsync::LocalBind(IP aSourceAddress,
00801 unsigned short usPort)
00802 {
00803 try
00804 {
00805 return CTCPSocket::Bind(aSourceAddress,
00806 usPort);
00807 }
00808 ERROR_HANDLER_RETURN("LocalBind",FALSE)
00809 }
00810
00811 void CTCPSocketAsync::SwitchEventsType()
00812 {
00813 m_bCloseEventsOnly=TRUE;
00814 }
00815
00816 CTCPSocketAsync::CTCPSocketOverider* CTCPSocketAsync::GetOverider()const
00817 {
00818 return m_pOverider;
00819 }
00820
00821 CTCPSocketAsync::operator const CTCPSocketAsync::CTCPSocketOverider*()const
00822 {
00823 return m_pOverider;
00824 }
00825
00826 IP CTCPSocketAsync::GetBindAddress()const
00827 {
00828 if (m_pLinkedSocket)
00829 return m_pLinkedSocket->GetBindAddress();
00830 else
00831 return LocalGetBindAddress();
00832 }
00833
00834 unsigned short CTCPSocketAsync::GetBindPort()const
00835 {
00836 if (m_pLinkedSocket)
00837 return m_pLinkedSocket->GetBindPort();
00838 else
00839 return LocalGetBindPort();
00840 }
00841
00842 IP CTCPSocketAsync::LocalGetBindAddress()const
00843 {
00844 try
00845 {
00846 return CTCPSocket::GetBindAddress();
00847 }
00848 ERROR_HANDLER_RETURN("LocalGetBindAddress",0)
00849 }
00850
00851 unsigned short CTCPSocketAsync::LocalGetBindPort()const
00852 {
00853 try
00854 {
00855 return CTCPSocket::GetBindPort();
00856 }
00857 ERROR_HANDLER_RETURN("LocalGetBindPort",0)
00858 }
00859
00860 BOOL CTCPSocketAsync::Accept(CTCPSocket* pNewSocket)
00861 {
00862 try
00863 {
00864 if (m_pLinkedSocket)
00865 return m_pLinkedSocket->Accept(pNewSocket);
00866 else
00867 return LocalAccept(pNewSocket);
00868 }
00869 ERROR_HANDLER_RETURN("Accept",FALSE)
00870 }
00871
00872 BOOL CTCPSocketAsync::LocalAccept(CTCPSocket* pNewSocket)
00873 {
00874 try
00875 {
00876 return CTCPSocket::Accept(pNewSocket);
00877 }
00878 ERROR_HANDLER_RETURN("LocalAccept",FALSE)
00879 }
00880
00881 SOCKET CTCPSocketAsync::Detach()
00882 {
00883
00884 RemoveSocketFromList();
00885
00886
00887 return CTCPSocket::Detach();
00888 }
00889
00890 KOMODIA_NAMESPACE_END