sockets.c

来自「mcf5307实验源代码」· C语言 代码 · 共 1,494 行 · 第 1/5 页

C
1,494
字号
        {   
            /*  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 = makeuport(sockptr->local_addr.port_num);

            if (port_num < 0)
            {
                /* allow others to use the TCP resource */
#ifdef PLUS
                NU_Release_Semaphore(&TCP_Resource);
#else
                NU_Release_Resource(TCP_Resource);
#endif
      
                return(NU_NO_PORT_NUMBER);
            }
        }

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

        /*  If makeuport created a port number for me then put it in
         *  the socket.  */
        if (sockptr->local_addr.port_num <= 0)
           sockptr->local_addr.port_num = (int16)intswap(uprt->in.u.dest);

        /*  Get his IP number.  */
        memcpy (uprt->out.i.ipdest, to->id.is_ip_addrs, 4);

        /*  Get his port number. */
        uprt->out.u.dest = intswap(dest_port);

        /*  Get my port number. */
        uprt->out.u.source = intswap((uint16)sockptr->local_addr.port_num);

        /*  Send the data. */
        count = netusend(uprt, (unsigned char *) buff, nbytes,
                         sockptr->so_options);

        /*  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. */
           
    /* allow others to use the TCP resource */
#ifdef PLUS
    NU_Release_Semaphore(&TCP_Resource);
#else
    NU_Release_Resource(TCP_Resource);
#endif
      
    /* return to caller */
    return(return_status);

}  /*  end of NU_Send_To  */

/****************************************************************************/
/* FUNCTION                                                                 */
/*                                                                          */
/*  NU_Recv                                                                 */
/*                                                                          */
/* DESCRIPTION                                                              */
/*                                                                          */
/*  This fuction will handle receiving data across a network during a       */
/*  connection oriented transfer.                                           */
/*                                                                          */
/* AUTHOR                                                                   */
/*                                                                          */
/*  Barb G. Harwell, Accelerated Technology Inc.                            */
/*                                                                          */
/*  CALLED FROM                                                             */
/*                                                                          */
/*      User Applications                                                   */
/*                                                                          */
/* CALLS                                                                    */
/*                                                                          */
/*    suspend_task                                                          */
/*                                                                          */
/* INPUTS                                                                   */
/*                                                                          */
/*  No inputs to the function                                               */
/*                                                                          */
/* OUTPUTS                                                                  */
/*                                                                          */
/*  No outputs from this function                                           */
/*                                                                          */
/* HISTORY                                                                  */
/*                                                                          */
/*  NAME                   DATE        REMARKS                              */
/*                                                                          */
/*  Barb G. Harwell      10/08/92      Initial version.                     */
/*  Craig L. Meredith    02/15/94      Clean up, added headers, interrupt   */
/*                                     version.                             */
/*                                                                          */
/****************************************************************************/

int16 NU_Recv (int16 socketd, char *buff, uint16 nbytes, int16 flags)
{
   int16 count;                              /* number of bytes written */
   int16 port_num, pnum;                     /* local machine's port number */
   int16 return_status = NU_NO_PORT_NUMBER;  /* initialized to error status */
   struct port *pprt;
   struct sock_struct *sockptr;            /* pointer to current socket */
      


   /*  Clean up warnings.  This parameter is used for socket compatibility
       but we are currently not making any use of it.  */
   unused_parameter = flags;

   /*  Validate the socket number.  */
   if ((socketd < 0) || (socketd >= NSOCKETS))
   {
       return (NU_INVALID_SOCKET);
   }

   if( (socket_list[socketd] == NU_NULL) )
   {
       return (NU_NOT_CONNECTED);
   }

   /*  Don't let anyone else in until we are through.  */
#ifdef PLUS
   NU_Obtain_Semaphore (&TCP_Resource, NU_SUSPEND);
#else  /* PLUS */
   NU_Request_Resource (TCP_Resource, NU_WAIT_FOREVER);
#endif /* !PLUS */
      
   /*  Pick up a pointer to the socket list. */
   sockptr = socket_list[socketd];

   /* 
    * Store the current task in the portlist.
    * We need to be able to restart this task after the NU_Stop
    */
   pnum = NU_GetPnum (sockptr);
   if (pnum >= 0)
   {
       pprt = portlist[pnum];
#ifdef PLUS
       pprt->RXTask = NU_Current_Task_Pointer();
       /* verify that a task is running */
       if (pprt->RXTask != NU_NULL)
#else  /* PLUS */
       pprt->RXTask = NU_Current_Task_ID();
       /* verify that a task is running */
       if (pprt->RXTask != NU_SYSTEM)
#endif /* !PLUS */
       {
           /* retrieve the local port number from the socket descriptor */
           port_num = sockptr->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->block == NU_TRUE) &&
                   (pprt->in.contain == 0) && (pprt->state == SEST))
               {
                   /*  Give up the resource until we can run again.  */
#ifdef PLUS
				   suspend_task (NU_Current_Task_Pointer ());
#else  /* PLUS */
				   suspend_task (NU_Current_Task_ID());
#endif /* !PLUS */
               }

               /* call tcp/ip library netread routine */
               count = netread ((uint16)pnum, buff, nbytes);

               /* verify success of transfer */
               if (count < 0)
               {
                   /* return an error status */
                   return_status = NU_NOT_CONNECTED;                   
               }
               else
               {
                   /* return number of bytes transferred */
                   return_status = count;
               }
           }
               
           /* clear the portlist task id */
#ifdef PLUS
           pprt->RXTask = NU_NULL;
#else  /* PLUS */
           pprt->RXTask = -1;
#endif /* !PLUS */

       }  /*  System is running, not a task  */
       else
       {
           /* return the error to the caller */
           return_status = NU_NOT_A_TASK;
       }
   } /* end found a port number from NU_GetPnum() */
           
   /* allow others to use the TCP resource */
#ifdef PLUS
   NU_Release_Semaphore (&TCP_Resource);
#else  /* PLUS */
   NU_Release_Resource (TCP_Resource);
#endif /* !PLUS */
      
   /* return to caller */
   return (return_status);
} /*  end of NU_Recv  */


/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      NU_Recv_From                                                     */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   This function is responsible for receiving data across a network    */
/*   during a connectionless transfer.                                   */
/*                                                                       */
/*  CALLED FROM                                                          */
/*                                                                       */
/*      User Applications                                                */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      NU_Obtain_Semaphore                                              */
/*      NU_Release_Semaphore                                             */
/*      NU_Get_UDP_Port                                                  */
/*      makeuport                                                        */
/*      intswap                                                          */
/*      neturead                                                         */
/*      suspend_task                                                     */
/*      NU_Current_Task_Pointer                                          */
/*                                                                       */
/*   History:                                                            */
/*    Barbara G. Harwell   10/08/92      Initial version.                */
/*                                                                       */
/*************************************************************************/
int16 NU_Recv_From(int16 socketd, char *buff, int16 nbytes, int16 flags,
 struct addr_struct *from, int16 *addrlen)
{
    struct uport       *uprt;
    int16 port_num;                           /* local machine's port number */
    int16 return_status = NU_NO_PORT_NUMBER;  /* initialized to error status */
    sshort my_port;
    struct sock_struct *sockptr;            /* pointer to current socket */

    /*  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 = (int16)*addrlen;

    *addrlen = sizeof(struct addr_struct);

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

    /*  Don't let anyone else in until we are through.  */
#ifdef PLUS
    NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else
    NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
#endif

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

    /* get my port number */
    my_port = sockptr->local_addr.port_num;

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

        /*  Check if the

⌨️ 快捷键说明

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