| < Day Day Up > |
|
The broadcast server and client, like the multicast server and client, are fundamentally derivatives of the datagram code patterns. This is again because broadcast communication is based upon the datagram model.
The C language source code for the broadcast server is shown in Listing 16.7. The server is broadcast-based, which means a single message emitted by the server is received by every client that is configured to receive broadcast datagrams (for the given port).
Because much of the discussion of the broadcast server is similar to the datagram server (shown in Listing 16.3), we discuss only some of the elements that make this server broadcast communication specific.
The first item to note is lines 17–18, where after the datagram socket is created, we enable the SO_BROADCAST option using setsockopt. This socket option permits a socket to send datagrams to the broadcast address (shown here as 255.255.255.255). This is the limited-broadcast address, because this particular broadcast variant will never cross a router. In this way, datagrams sent with this broadcast address are limited to the LAN of the originating host.
When setting up our address structure (lines 20–23), we follow a similar pattern of AF_INET, port and address. Note the use of inet_addr to convert the string address into the 32-bit network-byte-order variant. This address structure defines the recipient of the datagrams sent by the server, in this case the limited broadcast address, port 45003.
Finally, our broadcast server enters an infinite loop, emitting time strings every second. Note lines 34–35, in which the datagram is actually emitted. The sendto call is datagram-specific and is used to send a buffer to a named endpoint defined by a host and port. In this case, the named recipient was previously defined in our address structure (lines 20–23).
Listing 16.7 C language Daytime broadcast server.
1 #include <stdio.h> 2 #include <sys/socket.h> 3 #include <arpa/inet.h> 4 #include <unistd.h> 5 #include <time.h> 6 7 #define BCAST_PORT 45003 8 9 int main () 10 { 11 int sock, cnt, addrLen, on=1; 12 struct sockaddr_in addr; 13 char buffer[512]; 14 15 sock = socket(AF_INET, SOCK_DGRAM, 0); 16 17 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, 18 &on, sizeof(on)); 19 20 memset(&addr, 0, sizeof(addr)); 21 addr.sin_family = AF_INET; 22 addr.sin_port = htons(BCAST_PORT); 23 addr.sin_addr.s_addr = inet_addr("255.255.255.255"); 24 addrLen = sizeof(addr); 25 26 while (1) { 27 28 time_t t = time(0); 29 30 sprintf(buffer, "%s\n", ctime(&t)); 31 32 printf("sending %s", buffer); 33 34 cnt = sendto(sock, buffer, strlen(buffer), 0, 35 (struct sockaddr *)&addr, addrLen); 36 37 sleep(1); 38 39 } 40 41 }
The C language source code for the broadcast client is shown in Listing 16.8. As with the broadcast server, we concentrate on the differences to the standard datagram client.
After the client socket is created at line 14, the address structure (addr) is created and initialized in lines 16–19. We again define the family for Internet communication, and set the port to our broadcast port. For the client, we set the sin_addr field to the wildcard, INADDR_ANY. This permits the client to receive broadcast datagrams for port BCAST_PORT on any of the available host interfaces. The addressing information and the client socket are joined with the bind call at line 21.
A difference between the broadcast client and server is that the SO_BROADCAST socket option is not enabled for the client. This option is not used because the client does not send any broadcast datagrams; it only receives them.
Finally, the broadcast client receives datagrams using the recvfrom call at lines 27–28. The client saves the source address of the datagram, which is used only to print the source with the received buffer at lines 27–28.
Listing 16.8 C language Daytime broadcast client.
1 #include <stdio.h> 2 #include <sys/socket.h> 3 #include <arpa/inet.h> 4 #include <unistd.h> 5 6 #define BCAST_PORT 45003 7 8 int main () 9 { 10 int sock, cnt, addrlen; 11 struct sockaddr_in addr; 12 char buffer[512]; 13 14 sock = socket(AF_INET, SOCK_DGRAM, 0); 15 16 memset(&addr, 0, sizeof(addr)); 17 addr.sin_family = AF_INET; 18 addr.sin_port = htons(BCAST_PORT); 19 addr.sin_addr.s_addr = htonl(INADDR_ANY); 20 21 bind(sock, (struct sockaddr *)&addr, sizeof(addr)); 22 23 while (1) { 24 25 addrlen = sizeof(addr); 26 27 cnt = recvfrom(sock, buffer, sizeof(buffer), 0, 28 (struct sockaddr *)&addr, &addrlen); 29 buffer[cnt] = 0; 30 31 printf("%s : %s\n", inet_ntoa(addr.sin_addr), buffer); 32 33 } 34 35 }
| < Day Day Up > |
|