📄 socklib.c
字号:
return (ERROR); pSockFdMap[newFd] = pSockFunc; /* stuff fd map array */ return (newFd); }/********************************************************************************* connect - initiate a connection to a socket** If <s> is a socket of type SOCK_STREAM, this routine establishes a virtual* circuit between <s> and another socket specified by <name>. If <s> is of* type SOCK_DGRAM, it permanently specifies the peer to which messages* are sent. If <s> is of type SOCK_RAW, it specifies the raw socket upon* which data is to be sent and received. The <name> parameter specifies the* address of the other socket.** RETURNS* OK, or ERROR if the call fails.*/STATUS connect ( int s, /* socket descriptor */ struct sockaddr *name, /* addr of socket to connect */ int namelen /* length of name, in bytes */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->connectRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->connectRtn) (s, name, namelen)); }/******************************************************************************** connectWithTimeout - try to connect over a socket for a specified duration** This routine basically the same as connect(), except that it lets users * specify how long to keep trying to make the new connection.** If the <timeVal> is a NULL pointer, this routine acts exactly like* connect(). If <timeVal> is not NULL, it tries to establish a new* connection for the duration of the time specified in <timeVal>. After* that time, this routine reports a time-out error if the connection is not* established.** RETURNS: OK, or ERROR if a connection cannot be established.** SEE ALSO: connect()*/STATUS connectWithTimeout ( int sock, /* socket descriptor */ struct sockaddr *adrs, /* addr of the socket to connect */ int adrsLen, /* length of the socket, in bytes */ struct timeval *timeVal /* time-out value */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[sock]; if ((pSockFunc == NULL) || (pSockFunc->connectWithTimeoutRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->connectWithTimeoutRtn) (sock, adrs, adrsLen, timeVal)); }/********************************************************************************* sendto - send a message to a socket** This routine sends a message to the datagram socket named by <to>. The* socket <s> is received by the receiver as the sending socket.** The maximum length of <buf> is subject to the limits on UDP buffer* size. See the discussion of SO_SNDBUF in the setsockopt() manual* entry.** You can OR the following values into the <flags> parameter with this* operation:** .IP "MSG_OOB (0x1)" 26* Out-of-band data.** .IP "MSG_DONTROUTE (0x4)"* Send without using routing tables.* .LP** RETURNS* The number of bytes sent, or ERROR if the call fails.** SEE ALSO* setsockopt()*/int sendto ( FAST int s, /* socket to send data to */ FAST caddr_t buf, /* pointer to data buffer */ FAST int bufLen, /* length of buffer */ FAST int flags, /* flags to underlying protocols */ FAST struct sockaddr *to, /* recipient's address */ FAST int tolen /* length of <to> sockaddr */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->sendtoRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->sendtoRtn) (s, buf, bufLen, flags, to, tolen)); }/********************************************************************************* send - send data to a socket** This routine transmits data to a previously established connection-based* (stream) socket.** The maximum length of <buf> is subject to the limits* on TCP buffer size; see the discussion of SO_SNDBUF in the* setsockopt() manual entry.** You may OR the following values into the <flags> parameter with this* operation:** .IP "MSG_OOB (0x1)" 26* Out-of-band data.** .IP "MSG_DONTROUTE (0x4)"* Send without using routing tables.* .LP** RETURNS* The number of bytes sent, or ERROR if the call fails.** SEE ALSO* setsockopt(), sendmsg()**/int send ( FAST int s, /* socket to send to */ FAST char *buf, /* pointer to buffer to transmit */ FAST int bufLen, /* length of buffer */ FAST int flags /* flags to underlying protocols */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->sendRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->sendRtn) (s, buf, bufLen, flags)); }/********************************************************************************* sendmsg - send a message to a socket** This routine sends a message to a datagram socket. It may be used in* place of sendto() to decrease the overhead of reconstructing the* message-header structure (`msghdr') for each message.** For BSD 4.4 sockets a copy of the <mp>->msg_iov array will be made. This* requires a cluster from the network stack system pool of size * <mp>->msg_iovlen * sizeof (struct iovec) or 8 bytes.** RETURNS* The number of bytes sent, or ERROR if the call fails.** SEE ALSO* sendto()*/int sendmsg ( int sd, /* socket to send to */ struct msghdr *mp, /* scatter-gather message header */ int flags /* flags to underlying protocols */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[sd]; if ((pSockFunc == NULL) || (pSockFunc->sendmsgRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->sendmsgRtn) (sd, mp, flags)); }/********************************************************************************* recvfrom - receive a message from a socket** This routine receives a message from a datagram socket regardless of* whether it is connected. If <from> is non-zero, the address of the* sender's socket is copied to it. The value-result parameter <pFromLen>* should be initialized to the size of the <from> buffer. On return,* <pFromLen> contains the actual size of the address stored in <from>.** The maximum length of <buf> is subject to the limits on UDP buffer* size; see the discussion of SO_RCVBUF in the setsockopt() manual* entry.** You may OR the following values into the <flags> parameter with this* operation:** .IP "MSG_OOB (0x1)" 26* Out-of-band data.** .IP "MSG_PEEK (0x2)"* Return data without removing it from socket.* .LP** RETURNS* The number of number of bytes received, or ERROR if the call fails.** SEE ALSO* setsockopt()*/int recvfrom ( FAST int s, /* socket to receive from */ FAST char *buf, /* pointer to data buffer */ FAST int bufLen, /* length of buffer */ FAST int flags, /* flags to underlying protocols */ FAST struct sockaddr *from, /* where to copy sender's addr */ FAST int *pFromLen /* value/result length of <from> */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->recvfromRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->recvfromRtn) (s, buf, bufLen, flags, from, pFromLen)); }/********************************************************************************* recv - receive data from a socket** This routine receives data from a connection-based (stream) socket.** The maximum length of <buf> is subject to the limits on TCP buffer* size; see the discussion of SO_RCVBUF in the setsockopt() manual* entry.** You may OR the following values into the <flags> parameter with this* operation:** .IP "MSG_OOB (0x1)" 26* Out-of-band data.** .IP "MSG_PEEK (0x2)"* Return data without removing it from socket.* .LP** RETURNS* The number of bytes received, or ERROR if the call fails.** SEE ALSO* setsockopt()*/int recv ( FAST int s, /* socket to receive data from */ FAST char *buf, /* buffer to write data to */ FAST int bufLen, /* length of buffer */ FAST int flags /* flags to underlying protocols */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->recvRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->recvRtn) (s, buf, bufLen, flags)); }/********************************************************************************* recvmsg - receive a message from a socket** This routine receives a message from a datagram socket. It may be used in* place of recvfrom() to decrease the overhead of breaking down the* message-header structure `msghdr' for each message.** For BSD 4.4 sockets a copy of the <mp>->msg_iov array will be made. This* requires a cluster from the network stack system pool of size * <mp>->msg_iovlen * sizeof (struct iovec) or 8 bytes. ** RETURNS* The number of bytes received, or ERROR if the call fails.*/int recvmsg ( int sd, /* socket to receive from */ struct msghdr *mp, /* scatter-gather message header */ int flags /* flags to underlying protocols */ ) { SOCK_FUNC * pSockFunc = pSockFdMap[sd]; if ((pSockFunc == NULL) || (pSockFunc->recvmsgRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->recvmsgRtn) (sd, mp, flags)); }/********************************************************************************* setsockopt - set socket options** This routine sets the options associated with a socket.* To manipulate options at the "socket" level, <level> should be SOL_SOCKET.* Any other levels should use the appropriate protocol number.** OPTIONS FOR STREAM SOCKETS* The following sections discuss the socket options available for* stream (TCP) sockets.** .SS "SO_KEEPALIVE -- Detecting a Dead Connection"* Specify the SO_KEEPALIVE option to make the transport protocol (TCP)* initiate a timer to detect a dead connection:* .CS* setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof (optval));* .CE* This prevents an application from hanging on an invalid connection.* The value at <optval> for this option is an integer (type `int'),* either 1 (on) or 0 (off).** The integrity of a connection is verified by transmitting* zero-length TCP segments triggered by a timer, to force a response* from a peer node. If the peer does not respond after repeated* transmissions of the KEEPALIVE segments, the connection is dropped,* all protocol data structures are reclaimed, and processes sleeping* on the connection are awakened with an ETIMEDOUT error.** The ETIMEDOUT timeout can happen in two ways. If the connection is* not yet established, the KEEPALIVE timer expires after idling* for TCPTV_KEEP_INIT. If the connection is established, the* KEEPALIVE timer starts up when there is no traffic for* TCPTV_KEEP_IDLE. If no response is received from the peer after* sending the KEEPALIVE segment TCPTV_KEEPCNT times with interval* TCPTV_KEEPINTVL, TCP assumes that the connection is invalid.* The parameters TCPTV_KEEP_INIT, TCPTV_KEEP_IDLE, TCPTV_KEEPCNT, and* TCPTV_KEEPINTVL are defined in the file target/h/net/tcp_timer.h.** .SS "SO_LINGER -- Closing a Connection"* Specify the SO_LINGER option to determine whether TCP should perform a* "graceful" close:* .CS* setsockopt (sock, SOL_SOCKET, SO_LINGER, &optval, sizeof (optval));* .CE* For a "graceful" close in response to the shutdown of a connection, TCP * tries to make sure that all the unacknowledged data in transmission channel* are acknowledged, and the peer is shut down properly, by going through an* elaborate set of state transitions.** The value at <optval> indicates the amount of time to linger if* there is unacknowledged data, using `struct linger' in* target/h/sys/socket.h. The `linger' structure has two members:* `l_onoff' and `l_linger'. `l_onoff' can be set to 1 to turn on the* SO_LINGER option, or set to 0 to turn off the SO_LINGER option.* `l_linger' indicates the amount of time to linger. If `l_onoff' is* turned on and `l_linger' is set to 0, a default value TCP_LINGERTIME* (specified in netinet/tcp_timer.h) is used for incoming* connections accepted on the socket.** When SO_LINGER is turned on and the `l_linger' field is set to 0,* TCP simply drops the connection by sending out an RST if a* connection is already established; frees up the space for the TCP* protocol control block; and wakes up all tasks sleeping on the* socket.** For the client side socket, the value of `l_linger' is not changed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -