Programming with UDP – I Covered Subjects: • IPv4 Socket Address Structure • Byte Ordering Functions Address Access/Conversion Functions • Functions: • 1. 2. 3. 4. 5. socket() bind() sendto() recvfrom() close() Socket Address Structures Most socket functions require a pointer to a socket address structure as an argument. Each supported protocol defines its own socket address structure. The names of these structures begin with sockaddr_ and end with a unique suffix for each protocol suite. IPv4 Socket Address Structure Internet socket address structure is named sockaddr_in and defined in <netinet/in.h> IP address: struct in_addr { in_addr_t s_addr; }; /* 32-bit IP address */ /* network byte ordered */ TCP or UDP Address: struct sockaddr_in { uint8_t sin_len; /* length of structure*/ short sin_family; /* e.g., AF_INET */ ushort sin_port; /* TCP/UDP port */ struct in_addr; /* IP address */ char sin_zero[8]; /* unused */ }; All but sin_family in network byte order Note: Having sin_len simplifies handling variable length socket address structures. Generic Socket Address Structures Problem: A socket address is always passed by reference when passed as an argument to socket functions. But any socket call that takes one of these pointers as an argument must deal with socket address structures from ANY of the supported protocol families. A problem arises in how to declare the type of pointer that is passed. continued.. Solution: is to define a generic socket structure defined in <sys/socket.h> struct sockaddr{ uint8_t sa_len; sa_family_t sa_family; /* AF_INET, AF_INET6 .. */ char sa_data[14] /* protocol specific addr */ }; Example: int bind(int, struct sockaddr *, socklen_t); struct sockaddr_in serv; /* IPv4 address */ bind(sockfd, (struct sockaddr *)&serv,sizeof(serv)); If we omit this warning comes! Q: Why not do (void *)? Byte Ordering Big Endian vs. Little Endian ◦ Little Endian (Intel, DEC): Least significant byte of word is stored in the lowest memory address ◦ Big Endian (Sun, SGI, HP): Most significant byte of word is stored in the lowest memory address ◦ Network Byte Order = Big Endian Allows both sides to communicate Must be used for some data (i.e. IP Addresses) Good form for all binary data Byte Ordering Functions 16- and 32-bit conversion functions (for platform independence) Examples: int m, n; short int s,t; m = ntohl (n) net-to-host long (32-bit) translation s = ntohs (t) net-to-host short (16-bit) translation n = htonl (m) host-to-net long (32-bit) translation t = htons (s) host-to-net short (16-bit) translation Address Access/Conversion Functions in_addr_t inet_addr(const char* strptr); ◦ Translate dotted-decimal notation to IP address; returns -1 on failure, thus cannot handle broadcast value “255.255.255.255” int inet_aton(const char *strptr, struct in_addr *inaddr); ◦ Translate dotted-decimal notation to IP address; returns 1 on success, 0 on failure. char* inet_ntoa(struct in_addr inaddr); ◦ Translate IP address to ASCII dotted-decimal notation (e.g., “128.32.36.37”) UDP Client-Server Interaction Model socket() Function Create a socket ◦ int socket(int family, int type, int protocol); ◦ Returns file descriptor or -1. Fields: ◦ int family AF_INET AF_INET6 IPv4 protocols IPv6 protocols ◦ int type SOCK_DGRAM SOCK_STREAM for UDP datagrams for TCP streams ◦ int protocol (for AF_INET & AF_INET6 family sockets) IPPROTO_UDP IPPROTO_TCP UDP Transport TCP Transport bind() Function Bind a socket to a local IP address and port number ◦ int bind (int sockfd, struct sockaddr* myaddr, int addrlen); ◦ Returns 0 if OK or -1 on error. ◦ sockfd: socket file descriptor (returned from socket) ◦ myaddr: includes IP address and port number IP address: set by kernel if value passed is INADDR_ANY, else set by callerSpecifies Process Result port number: set by kernel if value passed is 0, else set by caller IP Address Port # ◦ addrlen: length of address structure INADDR_ANY 0 Kernel chooses IP addr& port # = sizeof (struct sockaddr_in) INADDR_ANY nonzero Kernel chooses IP addr, process specifies port # Local IP Addr 0 Process specifies IP addr, kernel assigns port # Local IP Addr nonzero Process specify both sendto() & recvfrom() Functions int sendto (int sockfd, char* buf, size_t nbytes, int flags, struct sockaddr* destaddr, int addrlen); ◦ Send a datagram to another UDP socket. Returns number of bytes written or -1. int recvfrom (int sockfd, char* buf, size_t nbytes, int flags, struct sockaddr* srcaddr, int* addrlen); ◦ Read a datagram from a UDP socket. Returns number of bytes read or -1. close() Function int close (int sockfd); Close a socket. ◦ Returns 0 on success, -1 on failure. ◦ sockfd: socket file descriptor (returned from socket) Closes communication on socket in both directions. ◦ All data sent before close are delivered to other side. After close, sockfd is not valid for reading or writing.