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

📄 sockets.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
        {
            /*  Make sure that he gave us the IP number. */
            if (TLS_Comparen (to->id.is_ip_addrs, (VOID *)IP_Null, 4))
            {
                /* allow others to use the TCP resource */
                NU_Release_Semaphore(&TCP_Resource);

                /* Switch back to user mode. */
                NU_USER_MODE();
      
                return(NU_INVALID_ADDRESS);
            }

            /* Pick up the foreign IP address and port number. */
            sockptr->s_foreign_addr.port_num = dest_port;
            *(UINT32 *)sockptr->s_foreign_addr.ip_num.is_ip_addrs = IP_ADDR(to->id.is_ip_addrs);

            /*  Make a port for this send if one does not already exist. */
            if (sockptr->s_local_addr.port_num > 0)
            {

                /*  Check if there is already a port structure set up
                 *  for this UDP communication.  */
                port_num = NU_Get_UDP_Pnum(sockptr);
            }
            else
                port_num = NU_IGNORE_VALUE;

            /*  If we did not find a port for this entry then we need to create
                one. */
            if (port_num == NU_IGNORE_VALUE)
            {
                port_num = UDP_Make_Port(sockptr->s_local_addr.port_num, socketd);

                if (port_num < 0)
                {
                    /* allow others to use the TCP resource */
                    NU_Release_Semaphore(&TCP_Resource);
      
                    /* Switch back to user mode. */
                    NU_USER_MODE();

                    return(NU_NO_PORT_NUMBER);
                }
            }

            /*  Fill in some of the fields that were not set up in UDP_Make_Port. */
            uprt = UDP_Ports[port_num];

            /*  If UDP_Make_Port created a port number for me then put it in
             *  the socket.  */
            if (sockptr->s_local_addr.port_num == 0)
               sockptr->s_local_addr.port_num = uprt->up_lport;

            /*  Get his IP number.  */
            uprt->up_faddr = IP_ADDR(to->id.is_ip_addrs);

            /*  Get his port number. */
            uprt->up_fport = dest_port;

            /*  Get my port number. */
            uprt->up_lport = sockptr->s_local_addr.port_num;

            /*  Send the data. */

            count = UDP_Send(uprt, buff, (INT32)nbytes);

            /*  Let them know if it worked OK. */
            if (count < 0)
                /* return an error status */
                return_status = NU_NO_DATA_TRANSFER;

            else
                /* return number of bytes transferred */
                return_status = count;

        }  /*  He specified a destination port. */
    }
    else
    {
        /* The device that this socket was communicating over has gone down. If 
           the device is a PPP device it is likely the physical connection has 
           been broken. If the device is ethernet and DHCP is being used, the 
           lease of the IP address may have expired. */
        return_status = NU_DEVICE_DOWN;
    }

    /* allow others to use the TCP resource */
    NU_Release_Semaphore(&TCP_Resource);

    /* Switch back to user mode. */
    NU_USER_MODE();

    /* return to caller */
    return(return_status);

}  /*  end of NU_Send_To  */

#endif /* INCLUDE_UDP == NU_TRUE */

#if (INCLUDE_TCP == NU_TRUE)

/*************************************************************************
*
*   FUNCTION                                                              
*                                                                         
*       NU_Recv                                                           
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       This fuction will handle receiving data across a network during a 
*       connection oriented transfer.                                     
*                                                                         
*   INPUTS                                                                
*                                                                         
*       socketd                                                           
*       *buff                                                             
*       nbytes                                                            
*       flags                                                             
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       Number of bytes received.                                         
*       NU_NO_PORT_NUMBER                                                 
*       NU_INVALID_SOCKET                                                 
*       NU_NOT_CONNECTED                                                  
*       NU_NO_ROUTE_TO_HOST
*       NU_CONNECTION_REFUSED
*       NU_MSG_TOO_LONG
*                                                                         
*************************************************************************/
INT32 NU_Recv (INT socketd, CHAR *buff, UINT16 nbytes, INT16 flags)
{
    INT32 count;                             /* number of bytes written */
    INT16 port_num;                          /* local machine's port number */
    INT32 return_status = NU_NO_PORT_NUMBER; /* initialized to error status */
    struct sock_struct *sockptr;             /* pointer to current socket */
    NU_SUPERV_USER_VARIABLES
        
    /*  Validate the socket number.  */
    if ((socketd < 0) || (socketd >= NSOCKETS))
    {
        return (NU_INVALID_SOCKET);
    }
    
    if( (SCK_Sockets[socketd] == NU_NULL) )
    {
        return (NU_NOT_CONNECTED);
    }

    /* Switch to supervisor mode. */
    NU_SUPERVISOR_MODE();

    /*  Clean up warnings.  This parameter is used for socket compatibility
        but we are currently not making any use of it.  */
    UNUSED_PARAMETER(flags);
    
    /*  Don't let anyone else in until we are through.  */
    NU_Obtain_Semaphore (&TCP_Resource, NU_SUSPEND);
    
    /*  Pick up a pointer to the socket list. */
    sockptr = SCK_Sockets[socketd];
    
    sockptr->s_RXTask = NU_Current_Task_Pointer();
    
    /* retrieve the local port number from the socket descriptor */
    port_num = sockptr->s_local_addr.port_num;
    
    /* verify that a port number exists */
    if (port_num)
    {
        /*
         * Check the socket's block flag to see if the caller wants to
         * wait for data or not, and if so, there is no data in the
         * input buffer and the connection is still alive.
         */
        if ( (sockptr->s_flags & SF_BLOCK) && (sockptr->s_recvbytes == 0)
            && (sockptr->s_state & SS_ISCONNECTED) )
        {
            /*  Give up the resource until we can run again.  */
            SCK_Suspend_Task (NU_Current_Task_Pointer ());
        }
        
        /* call tcp/ip library netread routine */
        count = TCPSS_Net_Read (sockptr, buff, nbytes);
        
        /* verify success of transfer - if not successful, either we are
        * not connected or an ICMP error message was received describing
        * the transmission problem */
        if (count < 0)
        {
        /* If the port number is not -1 and the icmp_error is negative
            * (an error value), then return that specific error value */
            if ( (sockptr->s_port_index != NU_IGNORE_VALUE) &&
                (TCP_Ports[sockptr->s_port_index]->icmp_error < 0) )
                return_status = TCP_Ports[sockptr->s_port_index]->icmp_error;
            
            /* Else we are not connected */
            else
                return_status = NU_NOT_CONNECTED;
            
        }
        
        /* Else, the receive was successful */
        else
        {
            /* return number of bytes transferred */
            return_status = count;
        }
    }
    
    /* clear the TCP_Ports task id */
    sockptr->s_RXTask = NU_NULL;
    
    /* allow others to use the TCP resource */
    NU_Release_Semaphore (&TCP_Resource);

    /* Switch back to user mode. */
    NU_USER_MODE();
    
    /* return to caller */
    return (return_status);
} /* NU_Recv */

#endif /* INCLUDE_TCP == NU_TRUE */

#if (INCLUDE_UDP == NU_TRUE)

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       NU_Recv_From                                                     
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function is responsible for receiving data across a network  
*       during a connectionless transfer.                                 
*                                                                       
*   INPUTS                                                                
*                                                                       
*       socketd                                                          
*       *buff                                                             
*       nbytes                                                           
*       flags                                                            
*       *from                                                             
*       *addrlen                                                          
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       Number of bytes received.                                        
*       NU_NO_PORT_NUMBER                                                
*       NU_INVALID_SOCKET                                                
*                                                                       
*************************************************************************/
INT32 NU_Recv_From(INT socketd, CHAR *buff, UINT16 nbytes, INT16 flags,
                   struct addr_struct *from, INT16 *addrlen)
{
    INT16  port_num;                            /* local machine's port number */
    INT32  return_status = NU_NO_PORT_NUMBER;   /* initialized to error status */
    UINT16 my_port;
    struct sock_struct *sockptr;                /* pointer to current socket */
    NU_SUPERV_USER_VARIABLES

    /*  Validate the socket number.  */
    if ((socketd < 0) || (socketd >= NSOCKETS) ||
        (SCK_Sockets[socketd] == NU_NULL))
        return(NU_INVALID_SOCKET);

    /* Switch to supervisor mode. */
    NU_SUPERVISOR_MODE();

    /*  Clean up warnings.  This parameter is used for socket compatibility
        but we are currently not making any use of it.  */
    UNUSED_PARAMETER(flags);
    UNUSED_PARAMETER(nbytes);
    UNUSED_PARAMETER(addrlen);

    /*  Don't let anyone else in until we are through.  */
    NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);

    /*  Pick up a pointer to the socket entry. */
    sockptr = SCK_Sockets[socketd];

    if (!(sockptr->s_state & SS_DEVICEDOWN))
    {
        /* get my port number */
        my_port = sockptr->s_local_addr.port_num;

        /* verify that a port number exists */
        if (my_port)
        {

            /*  Check if there is already a port structure set up
                for this UDP communication.  */
            port_num = NU_Get_UDP_Pnum(sockptr);

            if (port_num != NU_IGNORE_VALUE)
                /*  If there is a port number make sure that this is the one. */
                if (sockptr->s_local_addr.port_num != my_port)
                    port_num = NU_IGNORE_VALUE;

            /*  If we did not find a port for this entry then we need to create
                one. */
            if (port_num == NU_IGNORE_VALUE

⌨️ 快捷键说明

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