structure

Team-FLY

20.2 Simplified Interface for Connectionless Communication

Connectionless communication using UDP is based on the sendto and recvfrom functions. The UICI UDP connectionless communication interface has u_sendto, u_sendtohost, u_recvfrom and u_recvfromtimed that provide the same functionality, but with simpler parameters. Also, unlike the underlying UDP functions, the UICI UDP functions restart themselves after being interrupted by signals. Table 20.1 summarizes the UICI UDP interface to connectionless communication. To use these functions, you must compile your programs with both the UICI name and the UICI UDP libraries. Include both uiciname.h and uiciudp.h in your source files. Section 20.2.2 discusses error handling with the UICI UDP functions.

Table 20.1. Summary of UICI UDP calls.

UICI UDP

description

 int u_openudp(u_port_t port) 

creates a UDP socket and if port > 0, binds socket to port returns the socket file descriptor

 ssize_t u_recvfrom(int fd,        void *buf, size_t nbytes,        u_buf_t *ubufp) 

waits for up to nbytes from socket fd returns number of bytes received on return buf has received bytes and ubufp points to sender address

 ssize_t u_recvfromtimed(int fd,        void *buf, size_t nbytes,        u_buf_t *ubufp, double time) 

waits at most time seconds for up to nbytes from socket fd returns the number of bytes received on return buf has received bytes and ubufp points to sender address

 ssize_t u_sendto(int fd, void *buf,        size_t nbytes,        u_buf_t *ubufp) 

sends nbytes of buf on socket fd to the receiver specified by ubufp returns number of bytes actually sent

 ssize_t u_sendtohost(int fd,        void *buf, size_t nbytes,        char *hostn, u_port_t port) 

sends nbytes of buf on socket fd to receiver specified by hostn and port returns number of bytes actually sent

 void u_gethostname(u_buf_t *ubufp,        char *hostn, int hostnsize) 

copies host name specified by ubufp into buffer hostn of size hostnsize

 void u_gethostinfo(u_buf_t *ubufp,        char *info, inf infosize) 

copies printable string containing host name and port specified by ubufp into user -supplied buffer info of size infosize .

 int u_comparehost(u_buf_t *ubufp,        char *hostn, u_port_t port) 

returns 1 if host and port specified by ubufp match given host name and port number, or else returns 0

The u_openudp function returns a file descriptor that is a handle to a UDP socket. This function takes a single integer parameter, port , specifying the port number to bind to. If port is zero, the socket does not bind to a port. Typically, a server binds to a port and a client does not.

The u_recvfrom function reads up to nbytes from the file descriptor fd into the user-provided buffer buf and returns the number of bytes read. The u_recvfrom function fills in the user-supplied u_buf_t structure pointed to by ubufp with the address of the sender.

The u_recvfromtimed function is similar to u_recvfrom , but it takes an additional time parameter that specifies the number of seconds that u_recvfromtimed should wait for a message before returning with an error. The time parameter is a double , allowing fine-grained time values. Because messages may be lost, robust receivers call u_recvfromtimed to avoid blocking indefinitely.

The u_sendto function transmits nbytes from buf through the socket fd to the destination pointed to by ubufp . The u_sendto function requires a destination parameter because the communication endpoint is capable of sending to any host or receiving from any host. Use a u_buf_t value set by u_recvfrom to respond to a particular sender.

The u_sendtohost function is similar to u_sendto , but it requires a host name and port number rather than a pointer to a u_buf_t structure to specify the destination. Clients use u_sendtohost to initiate a communication with a server on a well-known port.

20.2.1 Host names and the u_buf_t structure

To be implementation-independent , applications that use UICI UDP should treat u_buf_t objects as opaque and use them in u_sendto without parsing. Appendix C provides an implementation of UICI UDP with IPv4, but it is also possible to implement UICI UDP with IPv6. The u_buf_t structure would be different for the two implementations . Three UICI UDP functions provide access to the information in the u_buf_t structure in an implementation-independent way. The u_gethostname function returns the host name encoded in a u_buf_t structure. The u_gethostinfo function returns a printable string containing a u_buf_t structure's information about host name and port number and can be used for debugging. The u_comparehost function returns 1 if the information in u_buf_t matches the specified host name and port number. Use u_comparehost to verify the identity of a sender.

20.2.2 UICI UDP return errors

The u_gethostname and u_gethostinfo functions return information in user-supplied buffers and cannot return an error code. The u_comparehost function returns 1 (true) if the hosts and ports match and 0 (false) if they do not. The other UICI UDP functions return “1 on error and set errno . If u_recvfromtimed times out, it sets errno to ETIME . If u_sendtohost cannot resolve the host name, it sets errno to EINVAL . Other errno settings match the underlying socket settings, as explained in Section 20.7. When a UICI UDP function returns an error and sets errno , you can use perror or strerror to display an appropriate error message, as long as you take into account these functions' lack of thread-safety.

20.2.3 UDP buffer size and UICI UDP

Messages sent under UDP are received atomically, meaning that a message sent with u_sendto or u_sendtohost is either transmitted entirely or not at all. A given implementation of UDP has a maximum message size. If you attempt to send a message that is too large, u_sendto or u_sendtohost returns “1 and sets errno to EMSGSIZE .

The u_recvfrom function reads exactly one message. If the message is smaller than nbytes , u_recvfrom returns the number of bytes actually read and its buf contains the entire message. If the message is larger than nbytes , u_recvfrom fills buf and truncates the message. In this case, u_recvfrom does not generate an error and returns the number of bytes put in the buffer (e.g., the size of the buffer).

Care must be taken to ensure that the receive buffer is large enough for the message, since UICI UDP truncates the message rather than generating an error when the buffer is too small. One way to handle this is to make the buffer one byte larger than the size expected and have the calling program generate an error if the buffer is completely filled.

Each UDP datagram is passed to the lower layers of the network protocol and encapsulated as a packet (header + data) in an IP datagram for transmission on the network. The network also imposes size limitations that affect transmission of datagrams. Each link in a path on the network has an MTU (maximum transmission unit), the largest chunk of information that a link can transmit. A datagram may be broken up into pieces (fragments) so that it can be physically transmitted along a link. These fragments are reassembled only when they reach the destination host. If any fragment is missing, the entire datagram is lost. While most UDP implementations allow datagrams of 8192 bytes, the typical network link has an MTU considerably smaller (e.g., 1500 bytes for Ethernet). As of this writing, most hosts and routers on the Internet use the IPv4 protocol for exchanging information. Under IPv4, hosts are not required to receive IP datagrams larger than 576 bytes, so many applications that use UDP limit their message size to fit in a datagram of this size, i.e., 576 “ 20(IP header) “ 8(UDP header) = 548 bytes.

Exercise 20.1

How would you modify u_recvfrom so that it detects messages that are too large for the buffer?

Answer:

Use malloc to modify u_recvfrom to accommodate a buffer size one byte larger than the buffer passed in. Receive the message into this larger buffer. If the number of bytes received is equal to this buffer size, u_recvfrom should return “1 and set errno to an appropriate value. One possible value to use is EMSGSIZE . Otherwise, u_recvfrom should copy the message into buf , the buffer that was passed as a parameter by the caller. In either case, u_recvfrom must free the temporary buffer.

Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net