Re: CAsyncSocket and Send



I'm using TCP/IP. I'm also sending/receivingbinary data (file transfer).

The sending side sends an 'f' char immediately before a file is sent. When
the 'f' is received, the receive file routine is called (which receives the
file name - 256 chars, the file size, and then the file data). After that,
occasionally there will be no more data (expected), however, sometimes there
more data on the socket. The receive file routine follows (adapted from Mike
O'Niell's CSocket file transfer tutorial). Thanks.

Vinoj

BOOL AsyncReceiveFile(CString FilePath){

BOOL bRet = TRUE; // return value
int dataLength, cbBytesRet, cbLeftToReceive, loop = 0;
BYTE* recdData = NULL;

CFile destFile;
char buff[256];
BOOL bFileIsOpen = FALSE;
Sleep(200);
CString strFileName;

//receive the filename
memset(buff, 0, sizeof(buff));
cbLeftToReceive = MAX_FILENAME_LENGTH;
do{
cbBytesRet = pAsyncClient->Receive(buff, cbLeftToReceive, 0);
if(cbBytesRet > 0)
cbLeftToReceive -= cbBytesRet;
else if(++loop > 1000)
return FALSE;
}
while(cbLeftToReceive >0);

strFileName = buff;
// open/create target file that receives the transferred data

if(!(bFileIsOpen = destFile.Open((LPCTSTR)strFileName,
CFile::modeCreate|CFile::modeWrite|CFile::typeBinary))){
MessageBeep(MB_ICONEXCLAMATION);

// Open Error Log File and Record Problem
}
return FALSE;
}

// get the file's size
Sleep(200);
cbLeftToReceive = sizeof(dataLength);
loop = 0;

do{
BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) -
cbLeftToReceive;
cbBytesRet = pAsyncClient->Receive( bp, cbLeftToReceive );

// test for errors and get out if they occurred
if(cbBytesRet == SOCKET_ERROR || cbBytesRet == 0){
int iErr = ::GetLastError();
if(iErr != WSAEWOULDBLOCK){

MessageBeep(MB_ICONEXCLAMATION);

// Open Error Log File and Record Problem }

return FALSE;
}
cbLeftToReceive += cbBytesRet;

//if data cannot be read
if(++loop > 1000)
return FALSE;
}

cbLeftToReceive -= cbBytesRet;



}
while (cbLeftToReceive > 0);

if((dataLength = ntohl( dataLength )) < 0){
MessageBeep(MB_ICONEXCLAMATION);

// Open Error Log File and Record Problem
}
return FALSE;
}


// now get the file in RECV_BUFFER_SIZE chunks at a time
Sleep(200);
recdData = new byte[BUFFER_SIZE];
cbLeftToReceive = dataLength;
loop = 0;
do{
int iiGet, iiRecd;

iiGet = (cbLeftToReceive<BUFFER_SIZE)?cbLeftToReceive:BUFFER_SIZE ;
iiRecd = pAsyncClient->Receive( recdData, iiGet );

// test for errors and get out if they occurred
if (iiRecd == SOCKET_ERROR || iiRecd == 0){
int iErr = ::GetLastError();
if(iErr != WSAEWOULDBLOCK){
//Record error

delete [] recdData;
return FALSE;
}
cbLeftToReceive += iiRecd;

if(++loop > 1000)
return FALSE;
}

// good data was retrieved, so accumulate
// it with already-received data
if(iiRecd > 0)
destFile.Write( recdData, iiRecd); // Write it
cbLeftToReceive -= iiRecd;


}
while ( cbLeftToReceive > 0 );


delete[] recdData;

if ( bFileIsOpen )
destFile.Close();

return bRet;
}

"Joseph M. Newcomer" wrote:

> Are you using TCP/IP or UDP?
>
> Are you making sure that, if you are handling strings, that you insert a terminating NUL
> character after the characters received? For example, if you have a 1K buffer, receive 4
> bytes representing 4 8-bit characters, then you must put a NUL in [4] a NUL character, or
> whatever is seen there will be seen as part of the string.
> joe
>
> On Tue, 10 Jan 2006 16:03:02 -0800, "Vinoj" <Vinoj@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> >Hello,
> >
> >I have two programs that use async sockets. Occasionally, there is garbage
> >(extra bytes) being sent after data, thus confusing my finite state machine.
> >Is there a way to track everytime the send() is called? Any ideas on why
> >this could be happening?
> >
> >I don't know if it matters, but the sending side of the program is written
> >in C and the receiving side is MFC. Thanks.
> >
> >Vinoj
> Joseph M. Newcomer [MVP]
> email: newcomer@xxxxxxxxxxxx
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm
>
.



Relevant Pages

  • Re: typecasting
    ... there are n number of options in buffer type char* ... have created a char array of pointers to point to all these n ... struct authProt auth; ... Adjust for the endianness of the incoming data (you do not need to worry about the endianness of the receiving machine doing it this way). ...
    (comp.lang.c)
  • Re: Clarification required about select vs wake_up race condition
    ... Our char driverdoes a ... In our poll(), ... it looks like it can set the state of the receiving ... any) or just getting back (iow, the task doesn't lose a cpu). ...
    (Linux-Kernel)
  • Re: Async Pro for serial communications
    ... in the loop, that pump responds. ... (psIdle, psXmitting, psWaitingResp, psReceiving); ... psReceiving:Log receiving timeout; ... If char signals beginning of message from pump ...
    (borland.public.delphi.thirdpartytools.general)
  • Re: How to deal with full-duplex communication?
    ... TCP/IP itself will not and cannot "lose" messages. ... is an error in your protocol. ... completely asynchronously as part of the design. ... At the level of socket io, you cannot really coordinate sending and receiving, ...
    (microsoft.public.vc.mfc)
  • Re: Read/Write socket Problem
    ... > receiving at the byte level. ... I am always writing 3 bytes from client, reading 3 bytes from server, ... char givenNo; ...
    (comp.unix.programmer)