📄 sockets.c
字号:
{
/* 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 + -