📄 contest.c
字号:
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");
cnt = fdSelect( (int)s1, &ibits, 0, 0, 0 );
if( !cnt )
ConPrintf("Select returned NULL - This is an error\n");
if( cnt < 0 )
{
tmp = fdError();
if( fClose && tmp == EBADF )
{
ConPrintf("fdSelect correctly returned EBADF\n");
s1 = INVALID_SOCKET;
}
else
ConPrintf("fdSelect returned unexpected error code (%d)\n",tmp);
}
else
{
if( fClose )
ConPrintf("Error: we should not be here!\n");
if( FD_ISSET(s1, &ibits) )
{
ConPrintf("Socket is now readable\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() == ECONNABORTED )
ConPrintf("Accept correctly returned ECONNABORTED\n");
else
ConPrintf("Accept returned bad error code\n");
}
}
leave:
if( s2 != INVALID_SOCKET )
fdClose(s2);
if( s1 != INVALID_SOCKET )
fdClose(s1);
ConPrintf("== End Test ==\n\n");
}
//----------------------------------------------------------------------
// CloseTask()
//
// Task to close a shared LISTEN socket
//----------------------------------------------------------------------
static void CloseTask( HANDLE hTaskParent, SOCKET s )
{
fdOpenSession( TaskSelf() );
ConPrintf("Child task spawned successfully - Calling fdClose()\n");
// Shutting down listen for read should wake our parent
fdClose(s);
// Small delay so we can see the main thread quitting immediately
// after the "Passed" message
TaskSleep(2000);
fdCloseSession( TaskSelf() );
TaskExit();
}
//----------------------------------------------------------------------
// ShutdownTask()
//
// Task to shutdown a shared LISTEN socket
//----------------------------------------------------------------------
static void ShutdownTask( HANDLE hTaskParent, SOCKET s )
{
fdOpenSession( TaskSelf() );
ConPrintf("Child task spawned successfully - Calling shutdown()\n");
// Shutting down listen for read should wake our parent
shutdown( s, SHUT_RD );
// Small delay so we can see the main thread quitting immediately
// after the "Passed" message
TaskSleep(2000);
fdCloseSession( TaskSelf() );
TaskExit();
}
//-------------------------------------------------------------------------
// StatusTest()
//
// Test the various status conditions of file descriptors
//-------------------------------------------------------------------------
static void StatusTest( IPN IPAddr )
{
SOCKET stcpl = INVALID_SOCKET;
SOCKET stcp_peer = INVALID_SOCKET;
SOCKET stcp_child = INVALID_SOCKET;
SOCKET stcp = INVALID_SOCKET;
SOCKET sudp = INVALID_SOCKET;
SOCKET pipe1 = INVALID_SOCKET;
SOCKET pipe2 = INVALID_SOCKET;
struct sockaddr_in sin1;
int error,status,size;
char *buffer;
buffer = mmAlloc(1024);
if( !buffer )
{
ConPrintf("failed to allocate temp buffer\n");
goto leave;
}
// Create TCP listen socket
stcpl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if( stcpl == 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( stcpl, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed bind (%d)\n",fdError());
goto leave;
}
// Start listening
if( listen( stcpl, 1) < 0 )
{
ConPrintf("failed listen (%d)\n",fdError());
goto leave;
}
//
// Setting socket buffer sizes on a listening socket only
// affects spawned sockets returned from accept()
//
// Set the TCP TX buffer to 1234;
size = 1234;
if( setsockopt( stcpl, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size) ) )
{
ConPrintf("failed setsockopt (%d)\n",fdError());
goto leave;
}
// Set the TCP RX buffer to 4321;
size = 4321;
if( setsockopt( stcpl, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size) ) )
{
ConPrintf("failed setsockopt (%d)\n",fdError());
goto leave;
}
// Create UDP socket
sudp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if( sudp == INVALID_SOCKET )
{
ConPrintf("failed socket create (%d)\n",fdError());
goto leave;
}
// Set the UDP RX buffer to 1024;
size = 1024;
if( setsockopt( sudp, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size) ) )
{
ConPrintf("failed setsockopt (%d)\n",fdError());
goto leave;
}
// Bind the socket
if( bind( sudp, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed bind (%d)\n",fdError());
goto leave;
}
// Connect the socket (to the same address)
if( connect( sudp, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed connect (%d)\n",fdError());
goto leave;
}
// Create the pipes
if( pipe( &pipe1, &pipe2 ) != 0 )
{
ConPrintf("pipe create failed\n");
goto leave;
}
// Create a TCP peer socket
stcp_peer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if( stcp_peer == INVALID_SOCKET )
{
ConPrintf("failed socket create (%d)\n",fdError());
goto leave;
}
ConPrintf("\nSocket Type Check\n");
error = fdStatus( stcpl, FDSTATUS_TYPE, &status );
ConPrintf("stcpl type is %d\n",status);
error |= fdStatus( sudp, FDSTATUS_TYPE, &status );
ConPrintf("sudp type is %d\n",status);
error |= fdStatus( pipe1, FDSTATUS_TYPE, &status );
ConPrintf("pipe1 type is %d\n",status);
error |= fdStatus( stcp_peer, FDSTATUS_RECV, &status );
ConPrintf("stcp_peer (unconnected) recv status = %d\n",status);
error |= fdStatus( stcp_peer, FDSTATUS_SEND, &status );
ConPrintf("stcp_peer (unconnected) send status = %d\n",status);
ConPrintf("\nListening Status Check\n");
// Get status of listen socket for recv
error |= fdStatus( stcpl, FDSTATUS_RECV, &status );
ConPrintf("stcpl connection available = %d\n",status);
ConPrintf("Calling connect...\n");
if( connect( stcp_peer, (PSA) &sin1, sizeof(sin1) ) < 0 )
{
ConPrintf("failed connect (%d)\n",fdError());
goto leave;
}
// Get status of listen socket for recv
error |= fdStatus( stcpl, FDSTATUS_RECV, &status );
ConPrintf("stcpl connection available = %d\n",status);
ConPrintf("Calling accept...\n");
size = sizeof( sin1 );
stcp_child = accept( stcpl, (PSA)&sin1, &size );
if( stcp_child == INVALID_SOCKET )
{
ConPrintf("failed accept (%d)\n",fdError());
goto leave;
}
// Get status of listen socket for recv
error |= fdStatus( stcpl, FDSTATUS_RECV, &status );
ConPrintf("stcpl connection available = %d\n",status);
// Get some socket buffer status
size = sizeof(size);
error |= getsockopt(stcp_peer, SOL_SOCKET, SO_SNDBUF, &status, &size);
ConPrintf("\nstcp_peer TCP send buffer size is %d\n",status);
error |= getsockopt(stcp_peer, SOL_SOCKET, SO_RCVBUF, &status, &size);
ConPrintf("stcp_peer TCP recv buffer size is %d\n",status);
error |= getsockopt(stcp_child, SOL_SOCKET, SO_SNDBUF, &status, &size);
ConPrintf("stcp_child TCP send buffer size is %d\n",status);
error |= getsockopt(stcp_child, SOL_SOCKET, SO_RCVBUF, &status, &size);
ConPrintf("stcp_child TCP recv buffer size is %d\n",status);
error |= getsockopt(sudp, SOL_SOCKET, SO_SNDBUF, &status, &size);
ConPrintf("sudp UDP send buffer size is %d\n",status);
error |= getsockopt(sudp, SOL_SOCKET, SO_RCVBUF, &status, &size);
ConPrintf("sudp UDP recv buffer size is %d\n",status);
// Get some other status
ConPrintf("\nCurrent RECV/SEND Status\n");
error |= fdStatus( stcp_child, FDSTATUS_RECV, &status );
ConPrintf("stcp_child recv status is %d\n",status);
error |= fdStatus( sudp, FDSTATUS_RECV, &status );
ConPrintf("sudp recv status is %d\n",status);
error |= fdStatus( pipe2, FDSTATUS_RECV, &status );
ConPrintf("pipe2 recv status is %d\n",status);
error |= fdStatus( stcp_peer, FDSTATUS_SEND, &status );
ConPrintf("stcp_peer send status is %d\n",status);
error |= fdStatus( sudp, FDSTATUS_SEND, &status );
ConPrintf("sudp send status is %d\n",status);
error |= fdStatus( pipe1, FDSTATUS_SEND, &status );
ConPrintf("pipe1 send status is %d\n",status);
// Send 1024 bytes to everyone
ConPrintf("\nCalling Send Data...\n");
send( stcp_peer, buffer, 1024, 0 );
send( sudp, buffer, 1024, 0 );
send( pipe1, buffer, 1024, 0 );
ConPrintf("\nCurrent RECV/SEND Status\n");
error |= fdStatus( stcp_child, FDSTATUS_RECV, &status );
ConPrintf("stcp_child recv status is %d\n",status);
error |= fdStatus( sudp, FDSTATUS_RECV, &status );
ConPrintf("sudp recv status is %d\n",status);
error |= fdStatus( pipe2, FDSTATUS_RECV, &status );
ConPrintf("pipe2 recv status is %d\n",status);
error |= fdStatus( stcp_peer, FDSTATUS_SEND, &status );
ConPrintf("stcp_peer send status is %d\n",status);
error |= fdStatus( sudp, FDSTATUS_SEND, &status );
ConPrintf("sudp send status is %d\n",status);
error |= fdStatus( pipe1, FDSTATUS_SEND, &status );
ConPrintf("pipe1 send status is %d\n",status);
// Recv 1024 bytes from everyone
ConPrintf("\nCalling Recv Data...\n");
recv( stcp_child, buffer, 1024, 0 );
recv( sudp, buffer, 1024, 0 );
recv( pipe2, buffer, 1024, 0 );
ConPrintf("\nCurrent RECV/SEND Status\n");
error |= fdStatus( stcp_child, FDSTATUS_RECV, &status );
ConPrintf("stcp_child recv status is %d\n",status);
error |= fdStatus( sudp, FDSTATUS_RECV, &status );
ConPrintf("sudp recv status is %d\n",status);
error |= fdStatus( pipe2, FDSTATUS_RECV, &status );
ConPrintf("pipe2 recv status is %d\n",status);
error |= fdStatus( stcp_peer, FDSTATUS_SEND, &status );
ConPrintf("stcp_peer send status is %d\n",status);
error |= fdStatus( sudp, FDSTATUS_SEND, &status );
ConPrintf("sudp send status is %d\n",status);
error |= fdStatus( pipe1, FDSTATUS_SEND, &status );
ConPrintf("pipe1 send status is %d\n",status);
// Close peers
ConPrintf("\nCalling close on receive side (tcp_child and pipe2)\n");
fdClose( stcp_child );
stcp_child = INVALID_SOCKET;
fdClose( pipe2 );
pipe2 = INVALID_SOCKET;
ConPrintf("\nCurrent RECV/SEND Status\n");
error |= fdStatus( stcp_peer, FDSTATUS_RECV, &status );
ConPrintf("stcp_peer recv status is %d\n",status);
error |= fdStatus( pipe1, FDSTATUS_RECV, &status );
ConPrintf("pipe1 recv status is %d\n",status);
error |= fdStatus( stcp_peer, FDSTATUS_SEND, &status );
ConPrintf("stcp_peer send status is %d\n",status);
error |= fdStatus( pipe1, FDSTATUS_SEND, &status );
ConPrintf("pipe1 send status is %d\n",status);
if( !error )
ConPrintf("\nTest Complete - No errors detected\n\n");
else
ConPrintf("\nTest Completed with Errors!\n\n");
leave:
if( stcpl != INVALID_SOCKET)
fdClose(stcpl);
if( stcp_peer != INVALID_SOCKET)
fdClose(stcp_peer);
if( stcp_child != INVALID_SOCKET)
fdClose(stcp_child);
if( stcp != INVALID_SOCKET)
fdClose(stcp);
if( sudp != INVALID_SOCKET)
fdClose(sudp);
if( pipe1 != INVALID_SOCKET)
fdClose(pipe1);
if( pipe2 != INVALID_SOCKET)
fdClose(pipe2);
if( buffer )
mmFree(buffer);
}
//-------------------------------------------------------------------------
// PollCounter()
//
// This function counts in a loop. It is launched as a low priority
// task the first time the "test counter" command it used. The current
// counter can then be checked/cleared by typing the "test counter"
// command again. Note there is no way to unload the counting loop, and
// it will interfere with IDLE loop based operations.
//-------------------------------------------------------------------------
static void PollCounter()
{
volatile int i;
PollRunning = 1;
for(;;)
{
for(i=0; i<10000; i++);
PollCount++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -