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 "TCPSocketAsyncMsg.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "Array_ptr.h"
00041 #include "GenericEvent.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 #define SEND_CHUNK 1500
00050
00051 KOMODIA_NAMESPACE_START
00052
00053 #define CTCPSocketAsyncMsg_Class "CTCPSocketAsyncMsg"
00054
00055 CTCPSocketAsyncMsg::CTCPSocketAsyncMsg() : CTCPSocketAsync(false)
00056 {
00057
00058 SetName(CTCPSocketAsyncMsg_Class);
00059 }
00060
00061 CTCPSocketAsyncMsg::~CTCPSocketAsyncMsg()
00062 {
00063 }
00064
00065 int CTCPSocketAsyncMsg::InternalReceiveMsg(char* pData,
00066 int iSize,
00067 int& iMoreMessages,
00068 bool bRecursed)
00069 {
00070 try
00071 {
00072
00073 iMoreMessages=0;
00074
00075
00076 int iMsgSize;
00077 if ((iMsgSize=CanExtractMsg(m_aData))>0)
00078 {
00079
00080 if (iSize<iMsgSize)
00081 {
00082
00083 iMoreMessages=-iMsgSize;
00084
00085
00086 return -1;
00087 }
00088
00089
00090 iMsgSize=ExtractMsg(m_aData,
00091 pData,
00092 iSize);
00093
00094
00095 if (iMsgSize>0)
00096 {
00097
00098 if (CanExtractMsg(m_aData)>0)
00099 {
00100
00101 iMoreMessages=1;
00102
00103
00104 return iMsgSize;
00105 }
00106 else if (bRecursed)
00107 return iMsgSize;
00108 }
00109 else if (iMsgSize<0)
00110 {
00111
00112 iMoreMessages=-iMsgSize;
00113
00114
00115 return -1;
00116 }
00117 else if (bRecursed)
00118
00119 return iMsgSize;
00120 }
00121
00122 else if (bRecursed)
00123 return 0;
00124
00125
00126
00127
00128
00129 char aData[4000];
00130
00131
00132 int iResult;
00133 iResult=Receive(aData,
00134 sizeof(aData));
00135
00136
00137 if (iResult<0)
00138 return iResult;
00139
00140
00141 if (iResult==0)
00142 return iMsgSize;
00143
00144
00145 for (int iCount=0;
00146 iCount<iResult;
00147 ++iCount)
00148 m_aData.push_back(aData[iCount]);
00149
00150
00151 int iNewMsg;
00152 iNewMsg=CanExtractMsg(m_aData);
00153
00154
00155 if (iMsgSize)
00156 {
00157
00158 if (iNewMsg>0)
00159
00160 iMoreMessages=1;
00161
00162
00163 return iMsgSize;
00164 }
00165
00166
00167 return InternalReceiveMsg(pData,
00168 iSize,
00169 iMoreMessages,
00170 true);
00171 }
00172 ERROR_HANDLER_RETURN("InternalReceiveMsg",-1)
00173 }
00174
00175
00176 int CTCPSocketAsyncMsg::ReceiveMsg(char* pData,
00177 int iSize,
00178 int& iMoreMessages)
00179 {
00180 return InternalReceiveMsg(pData,
00181 iSize,
00182 iMoreMessages,
00183 false);
00184 }
00185
00186 int CTCPSocketAsyncMsg::SendMsg(const char* pData,
00187 int iSize)
00188 {
00189 try
00190 {
00191
00192 char* pTmp;
00193 pTmp=new char[iSize+sizeof(DWORD)];
00194
00195
00196 CArray_ptr<char> pProtection(pTmp);
00197
00198
00199 memcpy(pTmp,
00200 &iSize,
00201 sizeof(DWORD));
00202
00203
00204 memcpy(pTmp+sizeof(DWORD),
00205 pData,
00206 iSize);
00207
00208
00209 int iResult;
00210 iResult=Send(pTmp,
00211 iSize+sizeof(DWORD));
00212
00213
00214 if (iResult==iSize+sizeof(DWORD))
00215 return iSize;
00216 else
00217 return iResult;
00218 }
00219 ERROR_HANDLER_RETURN("SendMsg",-1)
00220 }
00221
00222 int CTCPSocketAsyncMsg::SendMsg(const char* pData,
00223 int iSize,
00224 CGenericEvent* pStopEvent)
00225 {
00226 try
00227 {
00228
00229 char* pTmp;
00230 pTmp=new char[iSize+sizeof(DWORD)];
00231
00232
00233 CArray_ptr<char> pProtection(pTmp);
00234
00235
00236 memcpy(pTmp,
00237 &iSize,
00238 sizeof(DWORD));
00239
00240
00241 memcpy(pTmp+sizeof(DWORD),
00242 pData,
00243 iSize);
00244
00245
00246 DWORD dwSize(iSize);
00247 dwSize+=4;
00248
00249
00250
00251 DWORD dwPos;
00252 dwPos=0;
00253
00254 while (1)
00255 {
00256
00257 DWORD dwSend;
00258 if (dwPos+SEND_CHUNK>dwSize)
00259 dwSend=dwSize-dwPos;
00260 else
00261 dwSend=SEND_CHUNK;
00262
00263
00264 int iResult;
00265 iResult=Send(pTmp+dwPos,
00266 dwSend);
00267
00268
00269 if (iResult>0)
00270 if (iResult!=dwSend)
00271 return -2;
00272
00273 else if (!pStopEvent->Wait(0))
00274 return -3;
00275 else
00276 {
00277
00278 dwPos+=dwSend;
00279
00280
00281 if (dwPos==dwSize)
00282 return dwPos-sizeof(DWORD);
00283 }
00284 else if (GetLastError()!=WSAEWOULDBLOCK)
00285 return iResult;
00286
00287 else if (!pStopEvent->Wait(1))
00288 return -3;
00289 }
00290 }
00291 ERROR_HANDLER_RETURN("SendMsg",-1)
00292 }
00293
00294 int CTCPSocketAsyncMsg::ExtractMsg(CachedDeque& rData,
00295 char* pData,
00296 int iSize)const
00297 {
00298
00299 int iMsgSize;
00300 iMsgSize=CanExtractMsg(rData);
00301
00302
00303 if (!iMsgSize)
00304 return 0;
00305
00306
00307 if (iSize<iMsgSize)
00308 return -iMsgSize;
00309
00310
00311 rData.pop_front();
00312 rData.pop_front();
00313 rData.pop_front();
00314 rData.pop_front();
00315
00316
00317 for (int iCounter=0;
00318 iCounter<iMsgSize;
00319 ++iCounter)
00320 {
00321
00322 pData[iCounter]=rData.front();
00323
00324
00325 rData.pop_front();
00326 }
00327
00328
00329 return iMsgSize;
00330 }
00331
00332 int CTCPSocketAsyncMsg::CanExtractMsg(const CachedDeque& rData)const
00333 {
00334
00335 if (rData.size()<sizeof(DWORD))
00336 return 0;
00337
00338
00339 char aConvert[sizeof(DWORD)];
00340 aConvert[0]=rData[0];
00341 aConvert[1]=rData[1];
00342 aConvert[2]=rData[2];
00343 aConvert[3]=rData[3];
00344
00345
00346 DWORD dwSize;
00347 memcpy(&dwSize,
00348 aConvert,
00349 sizeof(DWORD));
00350
00351
00352 if (rData.size()-sizeof(DWORD)>=dwSize)
00353 return dwSize;
00354 else
00355 return 0;
00356 }
00357
00358 KOMODIA_NAMESPACE_END