⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miniserver.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 2 页
字号:
                     ( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,                       "Error in select call !!!\n" );                 )                continue;        } else {            if( FD_ISSET( miniServSock, &rdSet ) ) {                clientLen = sizeof( struct sockaddr_in );                connectHnd = accept( miniServSock,                                     ( struct sockaddr * )&clientAddr,                                     &clientLen );                if( connectHnd == UPNP_INVALID_SOCKET ) {                    DBGONLY( UpnpPrintf                             ( UPNP_INFO, MSERV, __FILE__, __LINE__,                               "miniserver: Error"                               " in accepting connection\n" );                         )                        continue;                }                schedule_request_job( connectHnd, &clientAddr );            }            //ssdp            CLIENTONLY( if( FD_ISSET( ssdpReqSock, &rdSet ) ) {                        readFromSSDPSocket( ssdpReqSock );}             )                if( FD_ISSET( ssdpSock, &rdSet ) ) {                    readFromSSDPSocket( ssdpSock );                }            if( FD_ISSET( miniServStopSock, &rdSet ) ) {                clientLen = sizeof( struct sockaddr_in );                memset( ( char * )&clientAddr, 0,                        sizeof( struct sockaddr_in ) );                byteReceived =                    recvfrom( miniServStopSock, requestBuf, 25, 0,                              ( struct sockaddr * )&clientAddr,                              &clientLen );                if( byteReceived > 0 ) {                    requestBuf[byteReceived] = '\0';                    DBGONLY( UpnpPrintf                             ( UPNP_INFO, MSERV, __FILE__, __LINE__,                               "Received response !!!  %s From host %s \n",                               requestBuf,                               inet_ntoa( clientAddr.sin_addr ) );                         )                        DBGONLY( UpnpPrintf                                 ( UPNP_PACKET, MSERV, __FILE__, __LINE__,                                   "Received multicast packet: \n %s\n",                                   requestBuf );                         )                        if( NULL != strstr( requestBuf, "ShutDown" ) )                        break;                }            }        }    }    shutdown( miniServSock, SD_BOTH );    UpnpCloseSocket( miniServSock );    shutdown( miniServStopSock, SD_BOTH );    UpnpCloseSocket( miniServStopSock );    shutdown( ssdpSock, SD_BOTH );    UpnpCloseSocket( ssdpSock );    CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );    CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );    free( miniSock );    gMServState = MSERV_IDLE;    return;}/*************************************************************************	Function :	get_port**	Parameters :*		int sockfd ; Socket Descriptor **	Description :	Returns port to which socket, sockfd, is bound.**	Return :	int, *		-1 on error; check errno*		 > 0 means port number**	Note :************************************************************************/static intget_port( int sockfd ){    struct sockaddr_in sockinfo;    int len;    int code;    int port;    len = sizeof( struct sockaddr_in );    code = getsockname( sockfd, ( struct sockaddr * )&sockinfo, &len );    if( code == -1 ) {        return -1;    }    port = ntohs( sockinfo.sin_port );    DBGONLY( UpnpPrintf             ( UPNP_INFO, MSERV, __FILE__, __LINE__,               "sockfd = %d, .... port = %d\n", sockfd, port );         )        return port;}/*************************************************************************	Function :	get_miniserver_sockets**	Parameters :*		MiniServerSockArray *out ;	Socket Array*		unsigned short listen_port ; port on which the server is listening *									for incoming connections	**	Description :	Creates a STREAM socket, binds to INADDR_ANY and *		listens for incoming connecttions. Returns the actual port which *		the sockets sub-system returned. *		Also creates a DGRAM socket, binds to the loop back address and *		returns the port allocated by the socket sub-system.**	Return :	int : *		UPNP_E_OUTOF_SOCKET - Failed to create a socket*		UPNP_E_SOCKET_BIND - Bind() failed*		UPNP_E_LISTEN	- Listen() failed	*		UPNP_E_INTERNAL_ERROR - Port returned by the socket layer is < 0*		UPNP_E_SUCCESS	- Success*		*	Note :************************************************************************/intget_miniserver_sockets( MiniServerSockArray * out,                        unsigned short listen_port ){    struct sockaddr_in serverAddr;    int listenfd;    int success;    unsigned short actual_port;    int reuseaddr_on = 0;    int sockError = UPNP_E_SUCCESS;    int errCode = 0;    int miniServerStopSock;    listenfd = socket( AF_INET, SOCK_STREAM, 0 );    if( listenfd <= 0 ) {        return UPNP_E_OUTOF_SOCKET; // error creating socket    }    // As per the IANA specifications for the use of ports by applications    // override the listen port passed in with the first available     if( listen_port < APPLICATION_LISTENING_PORT )        listen_port = APPLICATION_LISTENING_PORT;    memset( &serverAddr, 0, sizeof( serverAddr ) );    serverAddr.sin_family = AF_INET;    serverAddr.sin_addr.s_addr = htonl( INADDR_ANY );    // Getting away with implementation of re-using address:port and instead     // choosing to increment port numbers.    // Keeping the re-use address code as an optional behaviour that can be     // turned on if necessary.     // TURN ON the reuseaddr_on option to use the option.    if( reuseaddr_on ) {        //THIS IS ALLOWS US TO BIND AGAIN IMMEDIATELY        //AFTER OUR SERVER HAS BEEN CLOSED        //THIS MAY CAUSE TCP TO BECOME LESS RELIABLE        //HOWEVER IT HAS BEEN SUGESTED FOR TCP SERVERS        DBGONLY( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,                             "mserv start: resuseaddr set\n" );             )            sockError = setsockopt( listenfd,                                    SOL_SOCKET,                                    SO_REUSEADDR,                                    ( const char * )&reuseaddr_on,                                    sizeof( int )             );        if( sockError == UPNP_SOCKETERROR ) {            shutdown( listenfd, SD_BOTH );            UpnpCloseSocket( listenfd );            return UPNP_E_SOCKET_BIND;        }        sockError = bind( listenfd,                          ( struct sockaddr * )&serverAddr,                          sizeof( struct sockaddr_in )             );    } else {        do {            serverAddr.sin_port = htons( listen_port++ );            sockError = bind( listenfd,                              ( struct sockaddr * )&serverAddr,                              sizeof( struct sockaddr_in )                 );            if( sockError == UPNP_SOCKETERROR ) {                if( errno == EADDRINUSE )                    errCode = 1;            } else                errCode = 0;        } while( errCode != 0 );    }    if( sockError == UPNP_SOCKETERROR ) {        DBGONLY( perror( "mserv start: bind failed" );             )            shutdown( listenfd, SD_BOTH );        UpnpCloseSocket( listenfd );        return UPNP_E_SOCKET_BIND;  // bind failed    }    DBGONLY( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,                         "mserv start: bind success\n" );         )        success = listen( listenfd, SOMAXCONN );    if( success == UPNP_SOCKETERROR ) {        shutdown( listenfd, SD_BOTH );        UpnpCloseSocket( listenfd );        return UPNP_E_LISTEN;   // listen failed    }    actual_port = get_port( listenfd );    if( actual_port <= 0 ) {        shutdown( listenfd, SD_BOTH );        UpnpCloseSocket( listenfd );        return UPNP_E_INTERNAL_ERROR;    }    out->miniServerPort = actual_port;    if( ( miniServerStopSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) ==        UPNP_INVALID_SOCKET ) {        DBGONLY( UpnpPrintf( UPNP_CRITICAL,                             MSERV, __FILE__, __LINE__,                             "Error in socket operation !!!\n" );             )            shutdown( listenfd, SD_BOTH );        UpnpCloseSocket( listenfd );        return UPNP_E_OUTOF_SOCKET;    }    // bind to local socket    memset( ( char * )&serverAddr, 0, sizeof( struct sockaddr_in ) );    serverAddr.sin_family = AF_INET;    serverAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );    if( bind( miniServerStopSock, ( struct sockaddr * )&serverAddr,              sizeof( serverAddr ) ) == UPNP_SOCKETERROR ) {        DBGONLY( UpnpPrintf( UPNP_CRITICAL,                             MSERV, __FILE__, __LINE__,                             "Error in binding localhost!!!\n" );             )            shutdown( listenfd, SD_BOTH );        UpnpCloseSocket( listenfd );        shutdown( miniServerStopSock, SD_BOTH );        UpnpCloseSocket( miniServerStopSock );        return UPNP_E_SOCKET_BIND;    }    miniStopSockPort = get_port( miniServerStopSock );    if( miniStopSockPort <= 0 ) {        shutdown( miniServerStopSock, SD_BOTH );        shutdown( listenfd, SD_BOTH );        UpnpCloseSocket( miniServerStopSock );        UpnpCloseSocket( listenfd );        return UPNP_E_INTERNAL_ERROR;    }    out->stopPort = miniStopSockPort;    out->miniServerSock = listenfd;    out->miniServerStopSock = miniServerStopSock;    return UPNP_E_SUCCESS;}/*************************************************************************	Function :	StartMiniServer**	Parameters :*		unsigned short listen_port ; Port on which the server listens for *									incoming connections**	Description :	Initialize the sockets functionality for the *		Miniserver. Initialize a thread pool job to run the MiniServer*		and the job to the thread pool. If listen port is 0, port is *		dynamically picked**		Use timer mechanism to start the MiniServer, failure to meet the *		allowed delay aborts the attempt to launch the MiniServer.**	Return : int ;*		Actual port socket is bound to - On Success: *		A negative number UPNP_E_XXX - On Error   			*	Note :************************************************************************/intStartMiniServer( unsigned short listen_port ){    int success;    int count;    int max_count = 10000;    MiniServerSockArray *miniSocket;    ThreadPoolJob job;    if( gMServState != MSERV_IDLE ) {        return UPNP_E_INTERNAL_ERROR;   // miniserver running    }    miniSocket =        ( MiniServerSockArray * ) malloc( sizeof( MiniServerSockArray ) );    if( miniSocket == NULL )        return UPNP_E_OUTOF_MEMORY;    if( ( success = get_miniserver_sockets( miniSocket, listen_port ) )        != UPNP_E_SUCCESS ) {        free( miniSocket );        return success;    }    if( ( success = get_ssdp_sockets( miniSocket ) ) != UPNP_E_SUCCESS ) {        free( miniSocket );        shutdown( miniSocket->miniServerSock, SD_BOTH );        UpnpCloseSocket( miniSocket->miniServerSock );        shutdown( miniSocket->miniServerStopSock, SD_BOTH );        UpnpCloseSocket( miniSocket->miniServerStopSock );        return success;    }    TPJobInit( &job, ( start_routine ) RunMiniServer,               ( void * )miniSocket );    TPJobSetPriority( &job, MED_PRIORITY );    TPJobSetFreeFunction( &job, ( free_routine ) free );    success = ThreadPoolAddPersistent( &gRecvThreadPool, &job, NULL );    if( success < 0 ) {        shutdown( miniSocket->miniServerSock, SD_BOTH );        shutdown( miniSocket->miniServerStopSock, SD_BOTH );        shutdown( miniSocket->ssdpSock, SD_BOTH );        CLIENTONLY( shutdown( miniSocket->ssdpReqSock, SD_BOTH ) );        UpnpCloseSocket( miniSocket->miniServerSock );        UpnpCloseSocket( miniSocket->miniServerStopSock );        UpnpCloseSocket( miniSocket->ssdpSock );        CLIENTONLY( UpnpCloseSocket( miniSocket->ssdpReqSock ) );        return UPNP_E_OUTOF_MEMORY;    }    // wait for miniserver to start    count = 0;    while( gMServState != MSERV_RUNNING && count < max_count ) {        usleep( 50 * 1000 );    // 0.05s        count++;    }    // taking too long to start that thread    if( count >= max_count ) {        shutdown( miniSocket->miniServerSock, SD_BOTH );        shutdown( miniSocket->miniServerStopSock, SD_BOTH );        shutdown( miniSocket->ssdpSock, SD_BOTH );        CLIENTONLY( shutdown( miniSocket->ssdpReqSock, SD_BOTH ) );        UpnpCloseSocket( miniSocket->miniServerSock );        UpnpCloseSocket( miniSocket->miniServerStopSock );        UpnpCloseSocket( miniSocket->ssdpSock );        CLIENTONLY( UpnpCloseSocket( miniSocket->ssdpReqSock ) );        return UPNP_E_INTERNAL_ERROR;    }    return miniSocket->miniServerPort;}/*************************************************************************	Function :	StopMiniServer**	Parameters :*		void ;	**	Description :	Stop and Shutdown the MiniServer and free socket *		resources.**	Return : int ;*		Always returns 0 **	Note :************************************************************************/intStopMiniServer( void ){    int socklen = sizeof( struct sockaddr_in ),      sock;    struct sockaddr_in ssdpAddr;    char buf[256] = "ShutDown";    int bufLen = strlen( buf );    if( gMServState == MSERV_RUNNING )        gMServState = MSERV_STOPPING;    else        return 0;    sock = socket( AF_INET, SOCK_DGRAM, 0 );    if( sock == UPNP_INVALID_SOCKET ) {        DBGONLY( UpnpPrintf                 ( UPNP_INFO, SSDP, __FILE__, __LINE__,                   "SSDP_SERVER:StopSSDPServer: Error in socket operation !!!\n" );             )            return 0;    }    while( gMServState != MSERV_IDLE ) {        ssdpAddr.sin_family = AF_INET;        ssdpAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );        ssdpAddr.sin_port = htons( miniStopSockPort );        sendto( sock, buf, bufLen, 0, ( struct sockaddr * )&ssdpAddr,                socklen );        usleep( 1000 );        if( gMServState == MSERV_IDLE )            break;        isleep( 1 );    }    shutdown( sock, SD_BOTH );    UpnpCloseSocket( sock );    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -