📄 contest.c
字号:
ConPrintf("Connect Passed\n");
leave:
if( s != INVALID_SOCKET )
fdClose( s );
ConPrintf("\n== End Socket Error Reuse Test ==\n\n");
}
//----------------------------------------------------------------------
// ShareTest()
//
// Test ECHO with a shared TCP socket using two tasks
//----------------------------------------------------------------------
static void ShareTest( IPN IPAddr )
{
SOCKET s;
struct sockaddr_in sin1;
struct timeval timeout;
fd_set xbits;
int a;
ConPrintf("\n== Start Shared TCP Socket Echo Test ==\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);
// Configure our timeout to be 5 seconds
timeout.tv_sec = 5;
timeout.tv_usec = 0;
setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof( timeout ) );
setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof( timeout ) );
// Connect socket
if ( connect( s, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed connect (%d)\n",fdError());
goto leave;
}
a = OS_TASKPRINORM;
// Create a thread to receive data
if( !TaskCreate( TcpShareRX, "Receiver", OS_TASKPRINORM, 0x1000,
(UINT32)TaskSelf(), (UINT32)s, 0 ) )
goto leave;
// Create a thread to send us data
TaskCreate( TcpShareTX, "Sender", OS_TASKPRINORM, 0x1000,
(UINT32)TaskSelf(), (UINT32)s, 0 );
ConPrintf("Main task waiting with select() for test to complete\n");
FD_ZERO(&xbits);
FD_SET(s, &xbits);
fdSelect( (int)s, 0, 0, &xbits, 0 );
leave:
if( s != INVALID_SOCKET )
fdClose( s );
ConPrintf("== End Shared TCP Socket Echo Test ==\n\n");
}
//----------------------------------------------------------------------
// TcpShareRX()
//
// Task to receive data on a shared socket
//----------------------------------------------------------------------
static void TcpShareRX( HANDLE hTaskParent, SOCKET s, int *pFlag )
{
char *pBufRx;
HANDLE hBuffer;
UINT32 test,i,j;
int k;
UINT32 startS, startMS;
UINT32 endS, endMS;
fdOpenSession( TaskSelf() );
// Here we'll "share" socket 's' to up its reference count
// fdShare(s);
ConPrintf("RX Child task spawned successfully\n");
startS = llTimerGetTime( &startMS );
// Start Test
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 %l 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");
}
//----------------------------------------------------------------------
// ConnectFlood1()
//
// 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -