📄 contest.c
字号:
test = 8192;
i = 0;
for( j=0; j<TEST_ITER; j++ )
{
// Try and receive the buffer
while( i < test )
{
k = recvnc( s, (void **)&pBufRx, 0, &hBuffer );
if( k < 0 )
{
ConPrintf("RX Child recv failed (%d)\n",fdError());
goto leave;
}
if( !k )
{
ConPrintf("RX Child connection dropped\n");
goto leave;
}
recvncfree( hBuffer );
i += (UINT32)k;
}
i -= test;
}
// Verify reception size
if( i != 0 )
ConPrintf("RX Child received %d too many bytes\n",i);
if( j == TEST_ITER )
{
endS = llTimerGetTime( &endMS );
endS -= startS;
endS *= 1000;
endMS += endS;
endMS -= startMS;
endS = (endMS+500)/1000;
ConPrintf("Passed in %d ms, %d bytes/sec\n",endMS,(j*test)/endS);
}
// Closing our socket will eventually wake up our parent, but
// we want to test shutdown first. We shutdown read as a stronger
// form of the test. Shutting down write would cause the echo server
// to close the socket, which is the same as calling close() from
// our side.
shutdown( s, SHUT_RD );
// Small delay so we can see the main thread quitting immediately
// after the "Passed" message
TaskSleep(2000);
leave:
if( s != INVALID_SOCKET )
fdClose( s );
fdCloseSession( TaskSelf() );
TaskExit();
}
//-------------------------------------------------------------------------
// TcpShareTX()
//
// This function sends TCP data over a shared socket.
//-------------------------------------------------------------------------
static void TcpShareTX( HANDLE hTaskParent, SOCKET s )
{
UINT32 test,i;
char *pBuf = 0;
fdOpenSession( TaskSelf() );
// Here we'll "share" socket 's' to up its reference count
fdShare(s);
ConPrintf("TX Child task spawned successfully\n");
// Allocate a working buffer
if( !(pBuf = mmBulkAlloc( 8192 )) )
{
ConPrintf("TX Child failed temp buffer allocation\n");
goto leave;
}
// Start Test - Just Send
test = 8192;
for( i=0; i<TEST_ITER; i++ )
{
// Send the buffer
if( send( s, pBuf, (int)test, 0 ) < 0 )
{
ConPrintf("TX Child send failed (%d)\n",fdError());
break;
}
}
leave:
if( pBuf )
mmBulkFree( pBuf );
if( s != INVALID_SOCKET )
fdClose( s );
fdCloseSession( TaskSelf() );
TaskExit();
}
//----------------------------------------------------------------------
// ConnectTest1()
//
// Test Connect using non-Blocking IO
//----------------------------------------------------------------------
static void ConnectTest1( IPN IPAddr )
{
SOCKET s;
struct sockaddr_in sin1;
int tmp;
ConPrintf("\n== Start Non-Blocking Connect Test (polls connect()) ==\n");
// Create test socket
s = socket(AF_INET, SOCK_STREAMNC, IPPROTO_TCP);
if( s == INVALID_SOCKET )
{
ConPrintf("failed socket create (%d)\n",fdError());
goto leave;
}
// Prepare address for connect
bzero( &sin1, sizeof(struct sockaddr_in) );
sin1.sin_family = AF_INET;
sin1.sin_len = sizeof( sin1 );
sin1.sin_addr.s_addr = IPAddr;
sin1.sin_port = htons(7);
// Setup for non-blocking
tmp = 0;
setsockopt( s, SOL_SOCKET, SO_BLOCKING, &tmp, sizeof( tmp ) );
// Connect socket
while( connect( s, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
tmp = fdError();
if( tmp == EINPROGRESS )
ConPrintf("Connect returned EINPROGRESS\n");
else if( tmp == EALREADY )
ConPrintf("Connect returned EALREADY\n");
else if( tmp == EISCONN )
{
ConPrintf("Connect returned EISCONN\n");
break;
}
else if( tmp == ETIMEDOUT )
{
ConPrintf("Connect returned ETIMEDOUT\n");
break;
}
else if( tmp == ECONNREFUSED )
{
ConPrintf("Connect returned ECONNREFUSED\n");
break;
}
else
{
ConPrintf("Connect returned (unexpected) %d\n",tmp);
break;
}
TaskSleep( 100 );
}
if( !tmp )
ConPrintf("Connect returned success (IP address was local?)\n");
leave:
if( s != INVALID_SOCKET )
fdClose( s );
ConPrintf("== End Non-Blocking Connect Test ==\n\n");
}
//----------------------------------------------------------------------
// ConnectTest2()
//
// Test Connect using non-Blocking IO
//----------------------------------------------------------------------
static void ConnectTest2( IPN IPAddr )
{
SOCKET s;
struct sockaddr_in sin1;
int tmp;
struct timeval timeout;
fd_set obits;
int cnt;
ConPrintf("\n== Start Non-Blocking Connect Test (uses fdSelect()) ==\n");
// Create test socket
s = socket(AF_INET, SOCK_STREAMNC, IPPROTO_TCP);
if( s == INVALID_SOCKET )
{
ConPrintf("failed socket create (%d)\n",fdError());
goto leave;
}
// Prepare address for connect
bzero( &sin1, sizeof(struct sockaddr_in) );
sin1.sin_family = AF_INET;
sin1.sin_len = sizeof( sin1 );
sin1.sin_addr.s_addr = IPAddr;
sin1.sin_port = htons(7);
// Setup for non-blocking
tmp = 0;
setsockopt( s, SOL_SOCKET, SO_BLOCKING, &tmp, sizeof( tmp ) );
// Connect socket
if( connect( s, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
tmp = fdError();
if( tmp != EINPROGRESS )
{
ConPrintf("Connect returned error %d\n",tmp);
goto leave;
}
ConPrintf("Connect returned EINPROGRESS\n");
ConPrintf("Setting fdSelect() timeout to 8 seconds\n");
timeout.tv_sec = 8;
timeout.tv_usec = 0;
FD_ZERO(&obits);
FD_SET(s,&obits);
cnt = fdSelect( (int)s, 0, &obits, 0, &timeout );
if( !cnt )
ConPrintf("Connection timeout!\n");
else
{
ConPrintf("Socket reports writable\n");
if( connect( s, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
tmp = fdError();
if( tmp == EISCONN )
{
ConPrintf("Connect returned EISCONN\n");
goto leave;
}
else if( tmp == ECONNREFUSED )
{
ConPrintf("Connect returned ECONNREFUSED\n");
goto leave;
}
ConPrintf("Connect returned error %d\n",tmp);
}
}
ConPrintf("Connect failed\n");
}
if( !tmp )
ConPrintf("Connect returned success (IP address was local?)\n");
leave:
if( s != INVALID_SOCKET )
fdClose( s );
ConPrintf("== End Non-Blocking Connect Test ==\n\n");
}
//----------------------------------------------------------------------
// ConnectFlood()
//
// Test Connect Flood
//----------------------------------------------------------------------
static void ConnectFlood( IPN IPAddr )
{
SOCKET s;
struct sockaddr_in sin1;
int i;
ConPrintf("\n== Start Connect (TIMEWAIT) Flood Test ==\n");
for( i=0; i<1000; i++ )
{
// Create test socket
s = socket(AF_INET, SOCK_STREAMNC, IPPROTO_TCP);
if( s == INVALID_SOCKET )
{
ConPrintf("failed socket create (%d)\n",fdError());
goto leave;
}
// Prepare address for connect
bzero( &sin1, sizeof(struct sockaddr_in) );
sin1.sin_family = AF_INET;
sin1.sin_len = sizeof( sin1 );
sin1.sin_addr.s_addr = IPAddr;
sin1.sin_port = htons(7);
// Connect socket
if( connect( s, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed socket connect (%d)\n",fdError());
goto leave;
}
fdClose( s );
// We still need to give the timer loop some time to run
TaskSleep( 6 );
}
leave:
if( i < 1000 )
ConPrintf("Failed on iteration %d\n",i);
else
ConPrintf("Passed with %d iterations\n",i);
if( s != INVALID_SOCKET )
fdClose( s );
ConPrintf("== End Connect (TIMEWAIT) Flood Test ==\n\n");
}
//----------------------------------------------------------------------
// ShutdownTest1()
//
// Test shutdown/close of a listening socket in "accept"
//----------------------------------------------------------------------
static void ShutdownTest1( IPN IPAddr, int fClose )
{
SOCKET s1 = INVALID_SOCKET;
SOCKET s2 = INVALID_SOCKET;
int size,tmp;
struct sockaddr_in sin1;
if( fClose )
ConPrintf("\n== Test fdClose() on Listen/Accept sondition ==\n");
else
ConPrintf("\n== Test shutdown() on Listen/Accept sondition ==\n");
// Create test socket1
s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if( s1 == INVALID_SOCKET )
{
ConPrintf("failed socket create (%d)\n",fdError());
goto leave;
}
// Prepare address for bind
bzero( &sin1, sizeof(struct sockaddr_in) );
sin1.sin_family = AF_INET;
sin1.sin_len = sizeof( sin1 );
sin1.sin_addr.s_addr = IPAddr;
sin1.sin_port = htons(12345);
// Bind the socket
if( bind( s1, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed bind (%d)\n",fdError());
goto leave;
}
// Start listening
if( listen( s1, 1) < 0 )
{
ConPrintf("failed listen (%d)\n",fdError());
goto leave;
}
// Setup for non-blocking
tmp = 0;
setsockopt( s1, SOL_SOCKET, SO_BLOCKING, &tmp, sizeof( tmp ) );
ConPrintf("Calling non-blocking Accept()...\n");
size = sizeof( sin1 );
s2 = accept( s1, (PSA)&sin1, &size );
if( s2 != INVALID_SOCKET )
ConPrintf("Accept returned a socket - This is an error\n");
if( fdError() == EWOULDBLOCK )
ConPrintf("Accept correctly returned EWOULDBLOCK\n");
else
ConPrintf("Accept returned bad error code\n");
ConPrintf("Calling blocking Accept()...\n");
// Setup for blocking
tmp = 1;
setsockopt( s1, SOL_SOCKET, SO_BLOCKING, &tmp, sizeof( tmp ) );
// Create a thread to close or shutdown this socket
if( fClose )
{
if( !TaskCreate( CloseTask, "CloseTask", OS_TASKPRINORM,
0x1000, (UINT32)TaskSelf(), (UINT32)s1, 0 ) )
goto leave;
}
else
{
if( !TaskCreate( ShutdownTask, "ShutdownTask", OS_TASKPRINORM,
0x1000, (UINT32)TaskSelf(), (UINT32)s1, 0 ) )
goto leave;
}
size = sizeof( sin1 );
s2 = accept( s1, (PSA)&sin1, &size );
if( s2 != INVALID_SOCKET )
ConPrintf("Accept returned a socket - This is an error\n");
tmp = fdError();
if( tmp==EBADF && fClose )
{
ConPrintf("Accept correctly returned EBADF\n");
s1 = INVALID_SOCKET;
}
else if( tmp==ECONNABORTED && !fClose )
ConPrintf("Accept correctly returned ECONNABORTED\n");
else
ConPrintf("Accept returned unexpected error code (%d)\n",tmp);
leave:
if( s2 != INVALID_SOCKET )
fdClose(s2);
if( s1 != INVALID_SOCKET )
fdClose(s1);
ConPrintf("== End Test ==\n\n");
}
//----------------------------------------------------------------------
// ShutdownTest2()
//
// Test shutdown/close of a listening socket in "select"
//----------------------------------------------------------------------
static void ShutdownTest2( IPN IPAddr, int fClose )
{
SOCKET s1 = INVALID_SOCKET;
SOCKET s2 = INVALID_SOCKET;
int tmp,cnt,size;
fd_set ibits;
struct sockaddr_in sin1;
if( fClose )
ConPrintf("\n== Test fdClose() on Listen/Select sondition ==\n");
else
ConPrintf("\n== Test shutdown() on Listen/Select sondition ==\n");
// Create test socket1
s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if( s1 == INVALID_SOCKET )
{
ConPrintf("failed socket create (%d)\n",fdError());
goto leave;
}
// Prepare address for bind
bzero( &sin1, sizeof(struct sockaddr_in) );
sin1.sin_family = AF_INET;
sin1.sin_len = sizeof( sin1 );
sin1.sin_addr.s_addr = IPAddr;
sin1.sin_port = htons(12345);
// Bind the socket
if( bind( s1, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed bind (%d)\n",fdError());
goto leave;
}
// Start listening
if( listen( s1, 1) < 0 )
{
ConPrintf("failed listen (%d)\n",fdError());
goto leave;
}
// Create a thread to close or shutdown this socket
if( fClose )
{
if( !TaskCreate( CloseTask, "CloseTask", OS_TASKPRINORM,
0x1000, (UINT32)TaskSelf(), (UINT32)s1, 0 ) )
goto leave;
}
else
{
if( !TaskCreate( ShutdownTask, "ShutdownTask", OS_TASKPRINORM,
0x1000, (UINT32)TaskSelf(), (UINT32)s1, 0 ) )
goto leave;
}
FD_ZERO(&ibits);
FD_SET(s1, &ibits);
ConPrintf("Calling fdSelect() ...\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -