The use of (struct sockaddr *) is what you're supposed to do.

Your networking code, more or less, is fine. Your use of buffers... your server has a buffer overflow, and I suspect you have gaps in your knowledge regarding buffers, etc. Take this:
Code:
         n = recvfrom(sock, buf, 1024, 0, (struct sockaddr *) &from, &fromlen);
         if (n < 0) error("recvfrom");
 
         printf("Received a datagram.\n"); fflush(stdout);
         printf("%s\n", buf); fflush(stdout);
When you recvfrom() a buffer, the return value, n here, is - on success - the number of bytes recv'd. You ignore this, and send that buffer to printf(). printf() excepts a string and specifically, a string should be null-terminated. recvfrom(), since it doesn't work with strings, doesn't guarentee that buf is null-terminated. Thus, you possibly cause buffer overflows when you pass this buffer to printf(), if the sender doesn't send a trailing null. (And worse, looking at your client code - you don't!)

In short: Make sure your buffer is null terminated.
The general form is this, if you want a string:
Code:
n = recvfrom(sock, buf, SIZE_OF_BUFFER - 1, 0, .....);
// check n for errors
buf[n] = 0; // null terminate that buffer.
printf("%s\n", buf);
This also worries me:
Code:
     printf("Please enter the message: ");
     bzero(buffer, 256);
     fgets(buffer, 255, stdin);
There is no real reason to call bzero() here. Further, your buffer sizes to bzero() and fgets() differ. If you real the man pages for both functions, you'll see that bzero() just zeros an area, and that fgets will put in a trailing null, so you can pass 256 to both functions.