📄 socklib.c
字号:
if (iosFdValue (s) == ERROR || name == NULL) return (ERROR); pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->bindRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->bindRtn) (s, name, namelen)); }/********************************************************************************* listen - enable connections to a socket** This routine enables connections to a socket. It also specifies the* maximum number of unaccepted connections that can be pending at one time* (<backlog>). After enabling connections with listen(), connections are* actually accepted by accept().** RETURNS: OK, or ERROR if the socket is invalid or unable to listen.*/STATUS listen ( int s, /* socket descriptor */ int backlog /* number of connections to queue */ ) { SOCK_FUNC * pSockFunc = NULL; if (iosFdValue (s) == ERROR) return ERROR; pSockFunc = pSockFdMap[s]; if (pSockFunc == NULL || pSockFunc->listenRtn == NULL) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->listenRtn) (s, backlog)); }/********************************************************************************* accept - accept a connection from a socket** This routine accepts a connection on a socket, and returns a new socket* created for the connection. The socket must be bound to an address with* bind(), and enabled for connections by a call to listen(). The accept()* routine dequeues the first connection and creates a new socket with the* same properties as <s>. It blocks the caller until a connection is* present, unless the socket is marked as non-blocking.** The <addrlen> parameter should be initialized to the size of the available* buffer pointed to by <addr>. Upon return, <addrlen> contains the size in* bytes of the peer's address stored in <addr>.** WARNING* You must make sure that you do not close the file descriptor on which * a task is pending during an accept(). Although the accept() on the * closed file descriptor sometimes returns with an error, the accept() * can also fail to return at all. Thus, if you need to be able to close * a socket connections file descriptor asynchronously, you may need to * set up a semaphore-based locking mechanism that prevents the close * while an accept() is pending on the file descriptor.** RETURNS* A socket descriptor, or ERROR if the call fails.*/int accept ( int s, /* socket descriptor */ struct sockaddr *addr, /* peer address */ int *addrlen /* peer address length */ ) { int newFd; SOCK_FUNC * pSockFunc = NULL; if (iosFdValue (s) == ERROR) { netErrnoSet (EINVAL); return (ERROR); } pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->acceptRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } if ((newFd = (pSockFunc->acceptRtn) (s, addr, addrlen)) == ERROR) 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.** NOTE: If a socket with type SOCK_STREAM is marked non-blocking, this* routine will return ERROR with an error number of EINPROGRESS or EALREADY* if a connection attempt is pending. A later call will return ERROR and set* the error number to EISCONN once the connection is established. The* connection attempt must be repeated until that result occurs or until* this routine establishes a connection immediately and returns OK.** RETURNS: OK, or ERROR if the connection attempt does not complete.*/STATUS connect ( int s, /* socket descriptor */ struct sockaddr *name, /* addr of socket to connect */ int namelen /* length of name, in bytes */ ) { SOCK_FUNC * pSockFunc = NULL; if (name == NULL) { netErrnoSet (EINVAL); return (ERROR); } if (iosFdValue (s) == ERROR) return (ERROR); pSockFunc = pSockFdMap[s]; if ((pSockFunc == NULL) || (pSockFunc->connectRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } return ((pSockFunc->connectRtn) (s, name, namelen)); }/******************************************************************************** connectWithTimeout - attempt socket connection within a specified duration** Use this routine as an alternative to connect() when your application* requires a shorter time out on a connection attempt. By design, a TCP* connection attempt times out after 75 seconds if unsuccessful. Thus, a * blocking TCP socket connect() call might not return for 75 seconds. A * connectWithTimeout() call lets you reduce this time out by scheduling an * abort of the connection attempt if it is not successful before <timeVal>.* However, connectWithTimeout() does not actually change the TCP timeout* value. Thus, you cannot use connectWithTimeout() to lengthen the* connection time out beyond the TCP default.** In all respects other than the time out value, a connectWithTimeout() call * behaves exactly like connect(). Thus, if no application is listening for * connections at the other end, connectWithTimeout() returns immediately just * like connect(). If you specify a NULL pointer for <timeVal>, * connectWithTimeout() behaves exactly like a connect() call.** RETURNS: OK, or ERROR if a new connection is not established before timeout.** 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 = NULL; if (adrs == NULL) { netErrnoSet (EINVAL); return (ERROR); } if (iosFdValue (sock) == ERROR) return (ERROR); 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 = NULL; if (buf == NULL || to == NULL) { netErrnoSet (EINVAL); return (ERROR); } if (iosFdValue (s) == ERROR) return (ERROR); 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 const char * buf, /* pointer to buffer to transmit */ FAST int bufLen, /* length of buffer */ FAST int flags /* flags to underlying protocols */ ) { SOCK_FUNC * pSockFunc = NULL; if (buf == NULL || iosFdValue (s) == ERROR) return (ERROR); 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 = NULL; if (mp == NULL || iosFdValue (sd) == ERROR) { netErrnoSet (EINVAL); return (ERROR); } 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -