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 "TCPSocket.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 CTCPSocket_LOGNAME "CTCPSocket"
00053
00054 CTCPSocket::CTCPSocket(BOOL bRawSocket) : CSocket(bRawSocket)
00055 {
00056 try
00057 {
00058
00059 SetName(CTCPSocket_LOGNAME);
00060
00061
00062 InitializeTCP();
00063 }
00064 ERROR_HANDLER("CTCPSocket")
00065 }
00066
00067 CTCPSocket::CTCPSocket(SOCKET aSocket) : CSocket(aSocket)
00068 {
00069 try
00070 {
00071
00072 SetName(CTCPSocket_LOGNAME);
00073
00074
00075 InitializeTCP();
00076 }
00077 ERROR_HANDLER("CTCPSocket")
00078 }
00079
00080 CTCPSocket::~CTCPSocket()
00081 {
00082 }
00083
00084 BOOL CTCPSocket::Create()
00085 {
00086 try
00087 {
00088
00089 InitializeTCP();
00090
00091
00092 SetProtocol(IPPROTO_TCP);
00093
00094
00095 if (IsRaw())
00096 return CSocket::Create(IPPROTO_IP);
00097 else
00098 return CSocket::Create(IPPROTO_TCP);
00099 }
00100 ERROR_HANDLER_RETURN("Create",FALSE)
00101 }
00102
00103 BOOL CTCPSocket::Connect(IP aDestinationAddress,
00104 unsigned short usDestinationPort)
00105 {
00106 try
00107 {
00108 return Connect(0,
00109 aDestinationAddress,
00110 usDestinationPort);
00111 }
00112 ERROR_HANDLER_RETURN("Connect",FALSE)
00113 }
00114
00115 BOOL CTCPSocket::Connect(const std::string& rDestinationAddress,
00116 unsigned short usDestinationPort)
00117 {
00118 try
00119 {
00120 return Connect(0,
00121 rDestinationAddress,
00122 usDestinationPort);
00123 }
00124 ERROR_HANDLER_RETURN("Connect",FALSE)
00125 }
00126
00127 BOOL CTCPSocket::Connect(unsigned short usSourcePort,
00128 IP aDestinationAddress,
00129 unsigned short usDestinationPort)
00130 {
00131 try
00132 {
00133
00134 if (!CheckSocketValid())
00135 return FALSE;
00136
00137
00138 int iResult;
00139
00140
00141 sockaddr_in aSrc;
00142
00143
00144 memset(&aSrc,
00145 0,
00146 sizeof(aSrc));
00147 aSrc.sin_family=AF_INET;
00148 aSrc.sin_addr.s_addr=aDestinationAddress;
00149 aSrc.sin_port=htons(usDestinationPort);
00150
00151
00152 iResult=connect(GetHandle(),
00153 (sockaddr*)&aSrc,
00154 sizeof(aSrc));
00155
00156
00157 BOOL bBlocked;
00158 bBlocked=FALSE;
00159
00160
00161 if (iResult==GetErrorCode())
00162 {
00163
00164 if (WSAGetLastError()!=WSAEWOULDBLOCK)
00165 SetLastError("Connect");
00166 else
00167 {
00168
00169 bBlocked=TRUE;
00170 iResult=!GetErrorCode();
00171 }
00172 }
00173 else
00174
00175 SetLastError("Connect");
00176
00177 if (iResult!=GetErrorCode())
00178 {
00179
00180 if (!IsAsyncClass())
00181 SetConnectionStatus(TRUE);
00182
00183
00184 SetConnectedTo(aSrc);
00185 }
00186
00187
00188 if (!bBlocked)
00189 return iResult!=GetErrorCode();
00190 else
00191 return FALSE;
00192 }
00193 ERROR_HANDLER_RETURN("Connect",FALSE)
00194 }
00195
00196 BOOL CTCPSocket::Connect(unsigned short usSourcePort,
00197 const std::string& rDestinationAddress,
00198 unsigned short usDestinationPort)
00199 {
00200 try
00201 {
00202
00203 if (!CheckSocketValid())
00204 return FALSE;
00205
00206
00207 return Connect(usSourcePort,
00208 StringToLong(rDestinationAddress),
00209 usDestinationPort);
00210 }
00211 ERROR_HANDLER_RETURN("Connect",FALSE)
00212 }
00213
00214 BOOL CTCPSocket::Listen(unsigned long ulBackLog)
00215 {
00216 try
00217 {
00218
00219 if (!CheckSocketValid())
00220 return FALSE;
00221
00222
00223 int iResult;
00224 iResult=listen(GetHandle(),
00225 ulBackLog);
00226
00227
00228 if (iResult)
00229 {
00230
00231 SetLastError("Listen");
00232
00233
00234 return FALSE;
00235 }
00236 else
00237 return TRUE;
00238 }
00239 ERROR_HANDLER_RETURN("Listen",FALSE)
00240 }
00241
00242 CTCPSocket* CTCPSocket::Accept()
00243 {
00244 try
00245 {
00246
00247 if (!CheckSocketValid())
00248 return FALSE;
00249
00250
00251 SOCKET aSocket;
00252
00253
00254 sockaddr_in aConnected;
00255
00256
00257 int iSize;
00258 iSize=sizeof(aConnected);
00259
00260
00261 aSocket=accept(GetHandle(),
00262 (sockaddr*)&aConnected,
00263 &iSize);
00264
00265
00266 if (aSocket!=INVALID_SOCKET)
00267 {
00268
00269 CTCPSocket* pSocket;
00270 pSocket=new CTCPSocket(aSocket);
00271
00272
00273 pSocket->SetConnectedTo(aConnected);
00274 pSocket->SetConnectionStatus(TRUE);
00275
00276
00277 return pSocket;
00278 }
00279 else
00280 {
00281
00282 SetLastError("Accept");
00283
00284
00285 return NULL;
00286 }
00287 }
00288 ERROR_HANDLER_RETURN("Accept",NULL)
00289 }
00290
00291 void CTCPSocket::InitializeTCP()
00292 {
00293 try
00294 {
00295
00296 m_bConnected=FALSE;
00297 }
00298 ERROR_HANDLER("InitializeTCP")
00299 }
00300
00301 BOOL CTCPSocket::Accept(CTCPSocket* pNewSocket)
00302 {
00303 try
00304 {
00305
00306 if (!CheckSocketValid())
00307 return FALSE;
00308
00309
00310 SOCKET aNewSocket;
00311
00312
00313 sockaddr_in aAddress;
00314
00315
00316 int iSize;
00317 iSize=sizeof(aAddress);
00318
00319
00320 aNewSocket=accept(GetHandle(),
00321 (sockaddr*)&aAddress,
00322 &iSize);
00323
00324
00325 if (aNewSocket!=INVALID_SOCKET)
00326 {
00327
00328 SetAcceptance(pNewSocket,
00329 aNewSocket,
00330 aAddress);
00331
00332
00333 return TRUE;
00334 }
00335 else
00336 {
00337
00338 SetLastError("Accept");
00339
00340
00341 return FALSE;
00342 }
00343 }
00344 ERROR_HANDLER_RETURN("Accept",FALSE)
00345 }
00346
00347 void CTCPSocket::SetAcceptance(CTCPSocket* pNewSocket,
00348 SOCKET aSocket,
00349 sockaddr_in aAddress)const
00350 {
00351
00352 pNewSocket->BeforeAccept();
00353
00354
00355 pNewSocket->SetConnectedTo(aAddress);
00356 pNewSocket->AssignSocket(aSocket);
00357 pNewSocket->SetConnectionStatus(TRUE);
00358 pNewSocket->Accepted();
00359 }
00360
00361 int CTCPSocket::Send(const char *pBuffer,
00362 unsigned long ulBufferLength)
00363 {
00364 try
00365 {
00366
00367 if (!CheckSocketValid())
00368 return FALSE;
00369
00370
00371 int iResult;
00372
00373
00374 iResult=send(GetHandle(),
00375 pBuffer,
00376 ulBufferLength,
00377 NULL);
00378
00379
00380 if (iResult==GetErrorCode())
00381
00382 SetLastError("Send");
00383
00384
00385 return iResult;
00386 }
00387 ERROR_HANDLER_RETURN("Send",FALSE)
00388 }
00389
00390 void CTCPSocket::Accepted()
00391 {
00392 }
00393
00394 void CTCPSocket::SetConnectionStatus(BOOL bConnected)
00395 {
00396 m_bConnected=bConnected;
00397 }
00398
00399 BOOL CTCPSocket::IsConnected()const
00400 {
00401 return m_bConnected;
00402 }
00403
00404 BOOL CTCPSocket::IsAsyncClass()const
00405 {
00406 return FALSE;
00407 }
00408
00409 BOOL CTCPSocket::SetNagle(BOOL bNagle)
00410 {
00411 try
00412 {
00413
00414 if (!CheckSocketValid())
00415 return FALSE;
00416
00417
00418 if (bNagle)
00419 bNagle=FALSE;
00420 else
00421 bNagle=TRUE;
00422
00423
00424 if (setsockopt(GetHandle(),
00425 IPPROTO_TCP,
00426 TCP_NODELAY,
00427 (const char*)&bNagle,
00428 sizeof(bNagle))==GetErrorCode())
00429 {
00430
00431 ReportError("SetNagle","Failed to set nagle");
00432
00433
00434 SetLastError("SetNagle");
00435
00436
00437 return FALSE;
00438 }
00439
00440
00441 return TRUE;
00442 }
00443 ERROR_HANDLER_RETURN("SetNagle",FALSE)
00444 }
00445
00446 BOOL CTCPSocket::Close()
00447 {
00448 try
00449 {
00450
00451 if (!CheckSocketValid())
00452 return FALSE;
00453
00454
00455 if (CSocket::Close())
00456 {
00457
00458 SetConnectionStatus(FALSE);
00459
00460
00461 return TRUE;
00462 }
00463 else
00464 return FALSE;
00465 }
00466 ERROR_HANDLER_RETURN("Close",FALSE)
00467 }
00468
00469 void CTCPSocket::BeforeAccept()
00470 {
00471 }
00472
00473 KOMODIA_NAMESPACE_END
00474