Initial MSVC 2008 projects workspace
This commit is contained in:
318
l2packets/net_io/L2PacketReceiver.cpp
Normal file
318
l2packets/net_io/L2PacketReceiver.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
#include "stdafx.h"
|
||||
#include "L2Packet_NetLayer.h"
|
||||
#include "L2PacketReceiver.h"
|
||||
|
||||
//unsigned char l2p_packetReceive_dummyBuffer[2] = {0,0};
|
||||
|
||||
#ifdef L2PNET_ENABLE_OLD_RECVSEND
|
||||
|
||||
unsigned char *L2PacketReceive(
|
||||
unsigned int sock,
|
||||
long tv_sec, long tv_usec,
|
||||
unsigned int *rcvdLen )
|
||||
{
|
||||
if( !rcvdLen ) return NULL;
|
||||
(*rcvdLen) = 0;
|
||||
SOCKET s = (SOCKET)sock;
|
||||
if( s == INVALID_SOCKET ) return NULL;
|
||||
unsigned int plen = 0;
|
||||
int r = 0, rr = 0;
|
||||
unsigned char *packbuf = NULL;
|
||||
unsigned char *bufptr = NULL;
|
||||
//unsigned int buffree = 0;
|
||||
|
||||
// first try to receive packet len
|
||||
r = sock_tcp_wait_ready_to_recv( s, tv_sec, tv_usec );
|
||||
if( r <= 0 ) return NULL;
|
||||
r = recv( s, (char *)(&plen), 1, 0 );
|
||||
if( r == 0 ) return l2p_packetReceive_dummyBuffer;
|
||||
if( r != 1 ) return NULL;
|
||||
(*rcvdLen) = 1;
|
||||
|
||||
r = sock_tcp_wait_ready_to_recv( s, tv_sec, tv_usec );
|
||||
if( r <= 0 ) return NULL;
|
||||
r = recv( s, (char *)(&plen) + 1, 1, 0 );
|
||||
if( r == 0 ) return l2p_packetReceive_dummyBuffer;
|
||||
if( r != 1 ) return NULL;
|
||||
(*rcvdLen) = 2;
|
||||
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): Received plen byte 2; plen is: %04X (%d)\n",
|
||||
plen, plen );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
|
||||
if( plen == 0 ) return NULL;
|
||||
|
||||
packbuf = (unsigned char *)malloc( plen + 2 );
|
||||
if( !packbuf ) return NULL;
|
||||
bufptr = packbuf + 2;
|
||||
memcpy( packbuf, &plen, 2 );
|
||||
|
||||
unsigned int nBytesRcvd = 2; // packet len already received
|
||||
unsigned int nTimeouts = 0;
|
||||
unsigned int maxTimeouts = 5;
|
||||
while( nBytesRcvd < plen )
|
||||
{
|
||||
r = sock_tcp_wait_ready_to_recv( s, tv_sec, tv_usec );
|
||||
if( r > 0 ) // select() OK
|
||||
{
|
||||
rr = recv( s, (char *)bufptr, (plen-nBytesRcvd), 0 );
|
||||
if( rr > 0 ) // recv() OK, received rr bytes
|
||||
{
|
||||
bufptr += rr;
|
||||
nBytesRcvd += rr;
|
||||
nTimeouts = 0;
|
||||
}
|
||||
else if( rr == 0 ) // recv() returns 0 when connection closed by remote host?
|
||||
{
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): recv() returned 0; received %u bytes\n",
|
||||
nBytesRcvd );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts ) break;
|
||||
}
|
||||
else if( rr == -1 ) // recv() error?
|
||||
{
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): recv returned -1; total received %u bytes\n",
|
||||
nBytesRcvd );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts ) break;
|
||||
}
|
||||
}
|
||||
else if ( r == 0 ) // select() timeout
|
||||
{
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts )
|
||||
{
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): select too many timeouts, > maximum of %d\n",
|
||||
maxTimeouts );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
}
|
||||
}
|
||||
else if( r == -1 )
|
||||
{
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): select ERROR!\n" );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts )
|
||||
{
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): select too many timeouts, > maximum of %d\n",
|
||||
maxTimeouts );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
}
|
||||
}
|
||||
} // while
|
||||
|
||||
if( nBytesRcvd == plen )
|
||||
{
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): Received full packet len %u\n", plen );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
(*rcvdLen) = plen;
|
||||
return packbuf;
|
||||
}
|
||||
else if( nBytesRcvd < plen )
|
||||
{
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): ERROR: packet not received full (%u < %u)\n",
|
||||
nBytesRcvd, plen );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
free( packbuf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef L2P_NETWORK_DEBUGOUT
|
||||
printf( "L2PacketReceive(): ERROR: Unknown error!\n" );
|
||||
#endif // L2P_NETWORK_DEBUGOUT
|
||||
|
||||
free( packbuf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* L2PNET_ENABLE_OLD_RECVSEND */
|
||||
|
||||
|
||||
/**
|
||||
L2PacketReceive_malloc
|
||||
* Reads L2 packet from socket sock
|
||||
* Reads 1st 2 bytes, treates them as packet len, and then reads len bytes
|
||||
* places all received data (including 1st 2 bytes) in allocated by malloc() buffer.
|
||||
* Sets (*rcvdLen) to number of bytes received
|
||||
|
||||
* On read timeout (lWaitMiliSecs) returns NULL
|
||||
* On error returns NULL
|
||||
* returns pointer to buffer on success. caller should free returned buffer by free()
|
||||
*/
|
||||
unsigned char *L2PacketReceive_malloc( SOCKET sock, long lWaitMilliSecs, unsigned int *rcvdLen )
|
||||
{
|
||||
if( !rcvdLen ) return NULL;
|
||||
(*rcvdLen) = 0;
|
||||
if( sock == 0xFFFFFFFF ) return NULL;
|
||||
unsigned int plen = 0;
|
||||
int r = 0, rr = 0;
|
||||
unsigned char *packbuf = NULL;
|
||||
unsigned char *bufptr = NULL;
|
||||
|
||||
int rdyR = 0, rdyS = 0;
|
||||
|
||||
// first try to receive packet len
|
||||
r = L2PNet_select( sock, L2PNET_SELECT_READ, lWaitMilliSecs, &rdyR, &rdyS );
|
||||
if( r <= 0 ) return NULL;
|
||||
r = L2PNet_recv( sock, (unsigned char *)(&plen), 1 );
|
||||
if( r != 1 ) return NULL;
|
||||
(*rcvdLen) = 1;
|
||||
|
||||
r = L2PNet_select( sock, L2PNET_SELECT_READ, lWaitMilliSecs, &rdyR, &rdyS );
|
||||
if( r <= 0 ) return NULL;
|
||||
r = L2PNet_recv( sock, (unsigned char *)(&plen) + 1, 1 );
|
||||
if( r != 1 ) return NULL;
|
||||
(*rcvdLen) = 2;
|
||||
|
||||
if( plen == 0 ) return NULL;
|
||||
|
||||
packbuf = (unsigned char *)malloc( plen + 2 ); // possible speed loss <--------
|
||||
if( !packbuf ) return NULL;
|
||||
packbuf[0] = ((unsigned char *)&plen)[0];
|
||||
packbuf[1] = ((unsigned char *)&plen)[1];
|
||||
bufptr = packbuf + 2;
|
||||
|
||||
unsigned int nBytesRcvd = 2; // packet len already received
|
||||
unsigned int nTimeouts = 0;
|
||||
unsigned int maxTimeouts = 5;
|
||||
while( nBytesRcvd < plen )
|
||||
{
|
||||
(*rcvdLen) = nBytesRcvd;
|
||||
r = L2PNet_select( sock, L2PNET_SELECT_READ, lWaitMilliSecs, &rdyR, &rdyS );
|
||||
if( r > 0 ) // select() OK
|
||||
{
|
||||
rr = L2PNet_recv( sock, (unsigned char *)bufptr, (plen - nBytesRcvd) );
|
||||
if( rr > 0 ) // recv() OK, received rr bytes
|
||||
{
|
||||
bufptr += rr;
|
||||
nBytesRcvd += rr;
|
||||
nTimeouts = 0;
|
||||
}
|
||||
else if( rr <= 0 ) // recv() returns 0 when connection closed by remote host? or returns -1 on error
|
||||
{
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts ) break;
|
||||
}
|
||||
}
|
||||
else if ( r <= 0 ) // select() timeout or error
|
||||
{
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts ) break;
|
||||
}
|
||||
} // while
|
||||
|
||||
if( nBytesRcvd == plen ) // successful return
|
||||
{
|
||||
(*rcvdLen) = plen;
|
||||
return packbuf;
|
||||
}
|
||||
else if( nBytesRcvd < plen ) // received less than should, error
|
||||
{
|
||||
free( packbuf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// other error
|
||||
free( packbuf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
L2PacketReceive_buffer
|
||||
* Reads L2 packet from socket sock
|
||||
* Reads 1st 2 bytes, treates them as packet len, and then reads len bytes
|
||||
* places all received data (including 1st 2 bytes) in buffer recvBuffer.
|
||||
* Sets (*rcvdLen) to number of bytes received
|
||||
|
||||
* On read timeout (lWaitMiliSecs) returns 0
|
||||
* On error returns -1
|
||||
* returns 1 on success
|
||||
|
||||
* recvBuffer must point to big enough memory block (10 Kb min)
|
||||
*/
|
||||
int L2PacketReceive_buffer( SOCKET sock, long lWaitMilliSecs, unsigned int *rcvdLen, unsigned char *recvBuffer )
|
||||
{
|
||||
if( !rcvdLen || !recvBuffer ) return 0; // assert
|
||||
(*rcvdLen) = 0; // zero bytes received
|
||||
recvBuffer[0] = recvBuffer[1] = 0; // zero 1st 2 bytes in packet
|
||||
if( sock == 0xFFFFFFFF ) return 0; // assert
|
||||
unsigned int plen = 0; // receiving packet len
|
||||
int r = 0, rr = 0; // net functions results return codes
|
||||
unsigned char *bufptr = NULL; // current receive buffer pointer
|
||||
int rdyR = 0, rdyS = 0; // ready to recv, ready to send
|
||||
|
||||
// first try to receive packet len. receive 1st byte
|
||||
r = L2PNet_select( sock, L2PNET_SELECT_READ, lWaitMilliSecs, &rdyR, &rdyS );
|
||||
if( r <= 0 ) return r;
|
||||
r = L2PNet_recv( sock, (unsigned char *)(&plen), 1 );
|
||||
if( r <= 0 ) return r;
|
||||
(*rcvdLen) = 1;
|
||||
// receive 2nd byte
|
||||
r = L2PNet_select( sock, L2PNET_SELECT_READ, lWaitMilliSecs, &rdyR, &rdyS );
|
||||
if( r <= 0 ) return r;
|
||||
r = L2PNet_recv( sock, (unsigned char *)(&plen) + 1, 1 );
|
||||
if( r <= 0 ) return r;
|
||||
(*rcvdLen) = 2;
|
||||
|
||||
if( plen == 0 ) return 0; // protocol error - packet length 0 cannot be! minimum is 2
|
||||
|
||||
// set packet len in packet
|
||||
recvBuffer[0] = ((unsigned char *)&plen)[0];
|
||||
recvBuffer[1] = ((unsigned char *)&plen)[1];
|
||||
bufptr = recvBuffer + 2; // update current bufer pos to pass 1st 2 bytes
|
||||
|
||||
unsigned int nBytesRcvd = 2; // packet len already received
|
||||
unsigned int nTimeouts = 0; // number of timeouts on receive process
|
||||
unsigned int maxTimeouts = 5; // max.number of timeouts
|
||||
|
||||
// receive loop
|
||||
while( nBytesRcvd < plen )
|
||||
{
|
||||
(*rcvdLen) = nBytesRcvd;
|
||||
r = L2PNet_select( sock, L2PNET_SELECT_READ, lWaitMilliSecs, &rdyR, &rdyS );
|
||||
if( r > 0 ) // select() OK
|
||||
{
|
||||
rr = L2PNet_recv( sock, (unsigned char *)bufptr, (plen - nBytesRcvd) );
|
||||
if( rr > 0 ) // recv() OK, received rr bytes
|
||||
{
|
||||
bufptr += rr;
|
||||
nBytesRcvd += rr;
|
||||
nTimeouts = 0;
|
||||
}
|
||||
else if( rr <= 0 ) // recv() returns 0 when connection closed by remote host? or returns -1 on error
|
||||
{
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts ) break;
|
||||
}
|
||||
}
|
||||
else if ( r <= 0 ) // select() timeout or error
|
||||
{
|
||||
nTimeouts++;
|
||||
if( nTimeouts > maxTimeouts ) break;
|
||||
}
|
||||
} // while
|
||||
|
||||
if( nBytesRcvd == plen ) // successful return
|
||||
{
|
||||
(*rcvdLen) = plen;
|
||||
return 1;
|
||||
}
|
||||
else if( nBytesRcvd < plen ) // received less than should, error
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// other error
|
||||
return -1;
|
||||
}
|
Reference in New Issue
Block a user