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

📄 ws_tasks.c

📁 基于nucleus实时操作系统的webserver源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
*                                                                      
*     The main server function.  It receives the client connection  
*     and uses a queue to transmit the the connected socket once the    
*     it has been accepted.                                            
*                                                                      
* AUTHOR                                                               
*                                                                      
*     PicoServer Embedded Web Server                                    
*                                                                       
*     Copywrite (c) 1995 1996 1997 CNiT                                 
*                                                                       
*     Communication and Information Technology                          
*                                                                      
* INPUTS                                                               
*                                                                      
*     None.                                      
*                                                                      
* OUTPUTS                                                              
*                                                                      
*     None.                                    
*                                                                      
************************************************************************/

static VOID WS_Receive_Task(UNSIGNED  argc, VOID * argv)
{
    INT                 newsock; 
    INT                 socketd;                    /* the socket descriptor */
    struct addr_struct  servaddr;                   /* holds the server addre struct */
    struct addr_struct  client_addr;
    STATUS              status;
    short i;
    WS_SERVER           *this_server;

    /*  Remove warnings for unused parameters.  */
    UNUSED_PARAMETER(argc);
    UNUSED_PARAMETER(argv);

#ifndef WS_FS_IN_MEMORY
    /*  Register Task as File User */
    FAL_Become_File_User();
#endif


    /* Intialize global counters.  */
    this_server = &WS_Master_Server;

    /*  Print banner.  */
#ifdef  NU_WEBSERV_DEBUG
    printf("Nucleus Web Server\nHTTP 1.1 Server\n\n");
#endif 
    
    /* this process hangs in an endless loop
     * doing socket accept's. Each accept yields
     * a socket descriptor which is put on the Queue
     */

    /* open a connection via the socket interface */
    if ((socketd = NU_Socket(NU_FAMILY_IP, NU_TYPE_STREAM, 0)) >=0 )
    {

        /* fill in a structure with the server address */
        servaddr.family    = NU_FAMILY_IP;
        servaddr.port      = this_server->ws_port;
        
        /*  Set the ip address to IP addr ANY  */
        for(i = 0;i < 4;i++)
        {
            servaddr.id.is_ip_addrs[i] = 0;
        }

        /* make an NU_Bind() call to bind the server's address */
        if ((NU_Bind(socketd, &servaddr, 0))>=0)
        {
            /* be ready to accept connection requests */
            status = NU_Listen(socketd, 10);

            if (status == NU_SUCCESS)
            {
                while(1)
                {
                    /* block in NU_Accept until a client connects */
                    newsock = NU_Accept(socketd, &client_addr, 0);
                    if (newsock >= 0)
                    {
#ifdef NU_WEBSERV_DEBUG
                        printf("accept\n");
#endif
                        /* turn on the "block during a read" flag */    
                        NU_Fcntl(newsock, NU_SETFLAG, NU_BLOCK);

                        /* process the new connection */
                        NU_Send_To_Queue(&WS_Socket_Queue,
                                         &newsock, 1, NU_SUSPEND);
                            
                    }                               /* end successful NU_Accept */
                }                                   /* end for loop */
            }                                       /* end successful NU_Listen */
        }                                           /* end successful NU_Bind */
    }                                               /* end successful NU_Socket */
}


/************************************************************************
* FUNCTION                                                             
*                                                                      
*     WS_Worker_Task                                        
*                                                                      
* DESCRIPTION                                                          
*                                                                      
*     This function does the main processing of the client connections.
*     It first checks for a new socket in the global queue.  If one is
*     found, it adds it to it's local list of sockets.  The task then
*     locates a socket trying to communicate with the server and 
*     processes the connection.
*                                                                      
* AUTHOR                                                               
*                                                                      
*     Don Sharer, Accelerated Technology                                      
*                                                                      
* INPUTS                                                               
*                                                                      
*     None.                                      
*                                                                      
* OUTPUTS                                                              
*                                                                      
*     None.                                    
*                                                                      
************************************************************************/

static VOID WS_Worker_Task(UNSIGNED argc, VOID *argv)
{
    INT                     bytes_recieved;
    INT                     connection_bytes;
    INT                     sockfd = 0;
    WS_REQUEST              Req;
    FD_SET                  readfs, writefs, exceptfs;
    CHAR *                  line;
    CHAR *                  out_head;
    WS_REQ_DATA             * reqdat;
    WS_SOCK_LIST            http_sock;
    WS_SOCK_LIST            free_sock;
    WS_SOCKET_STRUCT        *hsock_ent;
    WS_SOCKET_STRUCT        *hsock_temp;
    
    STATUS                  status;
    UNSIGNED                suspend;
    UNSIGNED                actsize;
    
    CHAR                    *data_start;
    CHAR                    *s;
    INT                     header_length;
    INT                     content_length;

    struct sockaddr_struct  addr;
    INT16                   addr_length = sizeof(struct sockaddr_struct);

    /*  Remove warnings for unused parameters.  */
    UNUSED_PARAMETER(argc);
    UNUSED_PARAMETER(argv);
    
    NU_Allocate_Memory(&System_Memory, (VOID*)&reqdat, sizeof(WS_REQ_DATA), NU_SUSPEND);
    line = &reqdat->ws_lbuf[0];
    out_head = &reqdat->ws_out_head[0];
    
#ifndef WS_FS_IN_MEMORY
    /*  Each task must register task as a file user */
    FAL_Become_File_User();
#endif
    
    /* Initialize the pointers to the working list and the free list */
    http_sock.ws_sock_list_head = NU_NULL;
    http_sock.ws_sock_list_tail = NU_NULL;
    
    free_sock.ws_sock_list_head = NU_NULL;
    free_sock.ws_sock_list_tail = NU_NULL;
    
    /*  Initialize list of nodes to be used to store socket information */
    WS_Create_Socket_List(&free_sock);
    
    while(1) /* Endless loop processing HTTP requests */
    {   
        /* Initialize the bitmap */
        NU_FD_Init(&readfs);

        
        /* Check for a new socket in the queue, suspend if there are no
         * connections to proccess in the list or the queue
         */
        if(free_sock.ws_sock_list_head != NU_NULL)
        {
            if(http_sock.ws_sock_list_head == NU_NULL)
                suspend = (UNSIGNED)NU_SUSPEND;
            else
                suspend = (UNSIGNED)NU_NO_SUSPEND;
            
            status = NU_Receive_From_Queue(&WS_Socket_Queue,(VOID *)&sockfd,
                                           1, &actsize, suspend);
            
            if(status == NU_SUCCESS)
                WS_Add_Socket_Entry(&http_sock, &free_sock, sockfd);
        }

        if(!WS_Master_Server.ws_ip[0])
        {
            /*  We now must get the Ip address of the device the connection was made on */
            NU_Get_Sock_Name(sockfd, &addr, &addr_length);
            IP_ADDR_COPY(WS_Master_Server.ws_ip , addr.ip_num.is_ip_addrs);    
        }
        
        /* Check for any dead connections */       
        hsock_ent = http_sock.ws_sock_list_head;
        
        while(hsock_ent)
        {
            if((NU_Is_Connected(hsock_ent->ws_socketd) == NU_TRUE) &&
                NU_Retrieve_Clock() < (hsock_ent->ws_time_click + WS_SOCKET_GRACEFUL_TIMEOUT))
            {
                /* This connection is still good, mark it in the bitmap */
                NU_FD_Set(hsock_ent->ws_socketd, &readfs);
                hsock_ent = hsock_ent->ws_next_link;
            }
            else
            {
                /* This connection is bad, close it and remove it from the list */
                NU_Close_Socket(hsock_ent->ws_socketd);
                hsock_temp = hsock_ent;
                hsock_ent = hsock_ent->ws_next_link;
                WS_Remove_Socket_Entry(&http_sock,&free_sock,hsock_temp);
            }
        }

         
        /*  Select on all of the SOCKETS within the System based on an HTTP timeout */
        if((NU_Select(NSOCKETS, &readfs, &writefs, &exceptfs, (TICKS_PER_SECOND >> 1))) == NU_SUCCESS)
        {
            /*  Find which socket has the incoming data available */
            for(hsock_ent = http_sock.ws_sock_list_head; hsock_ent; hsock_ent = hsock_ent->ws_next_link)
            {
                if(NU_FD_Check(hsock_ent->ws_socketd, &readfs) == NU_TRUE)
                {
                    /* This socket has data ready to proccess */
                    sockfd = hsock_ent->ws_socketd;
                    
                    /* Initialize the following before processing the connection */
                    connection_bytes    = 0;
                    header_length       = 0;
                    content_length      = 0;
                    data_start          = 0;
                    status              = NU_SUCCESS;
                    
                    Req.ws_hp.ws_header       = NU_NULL;
                    Req.ws_hp.ws_data         = NU_NULL;
                    
                    Req.ws_hp.ws_tsize        = 0;
                    Req.ws_hp.ws_free_buf_sz  = 0;
                    Req.ws_hp.ws_header_size  = 0;
                    Req.ws_hp.ws_header_set   = 0;
                    Req.ws_hp.ws_no_pluginhead = 0;  

                    do
                    {    
                        bytes_recieved = (INT)(NU_Recv(sockfd, line + connection_bytes,
                                         (UINT16)(WS_RECEIVE_SIZE - connection_bytes), (INT16)NU_NO_SUSPEND));
                        
                        if (bytes_recieved < 0)
                        {
#ifdef NU_WEBSERV_DEBUG
                            printf("\n NU_Recv error\n");
#endif
                            NU_Close_Socket(hsock_ent->ws_socketd);
                            WS_Remove_Socket_Entry(&http_sock,&free_sock,hsock_ent);
                            status = -1;
                            break;
                        }
                        
                        connection_bytes = connection_bytes + bytes_recieved;
                        
                        /*  Null Terminate String */
                        line[connection_bytes] = 0;
                        
                        /* We want to get the entire request before calling the plugin.  In the case of
                        * file upload, the entire content won't fit, so don't try to get more than the header.
                        */
                        if (data_start == 0)
                        {
                        /* The data starts after the first CRLFCRLF delimiter.  
                        * Keep receiving until we see that delimiter. 
                            */
                            if( (data_start = HTTP_In_String("\r\n\r\n",line)) == FAILURE ) 

⌨️ 快捷键说明

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