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 + -
显示快捷键?