Datagrams have the following characteristics:
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define BUFSIZE 8000
main(int argc, char * argv[])
{
int sock, nread, rc, server_len, client_len;
struct sockaddr_in server, client;
char buff[BUFSIZE];
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("SERVER socket ");
exit(1);
}
// Let the System to fill in the Port number this time
// This can be done with connection oriented sockets as well.
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
if (argc <= 1)
server.sin_port = htons(0); // pick any free port
else
{
server.sin_port = htons(atoi(argv[1]));
}
if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
{
perror("SERVER bind ");
close(sock);
exit(2);
}
server_len = sizeof(server);
// We call getsockname so we can look at what port number
// the system actually picked.
if (getsockname(sock, (struct sockaddr *)&server, &server_len) < 0)
{
perror("SERVER getsockname ");
close(sock);
exit(3);
}
printf("Server using port %d\n", ntohs(server.sin_port));
for (;;)
{
client_len = sizeof(client);
memset(buff, 0, BUFSIZE);
// recvfrom returns the address of who sent the packet
// in the client structure
nread = recvfrom (sock, buff, BUFSIZE, 0,
(struct sockaddr *)&client, &client_len);
if (nread < 0)
{
perror("SERVER recvfrom ");
close(sock);
exit(4);
}
buff[nread] = 0;
printf("received: %s\n", buff);
// We use the client structure to know who to send the
// response to.
rc = sendto(sock, buff, strlen(buff), 0,
(struct sockaddr *)&client, client_len);
if (rc < 0)
{
perror("SERVER sendto ");
close(sock);
exit(5);
}
} // end of for loop
}
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define BUFSIZE 8000
main(int argc, char * argv[])
{
int sock, nread, rc, server_len, client_len;
int port;
struct sockaddr_in server, client;
char buff[BUFSIZE];
char hostname[64];
char *str;
struct hostent *hp;
if (argc < 2)
{
printf("Useage: %s port [hostname]", argv[0]);
exit(0);
}
port = atoi(argv[1]);
gethostname(hostname, sizeof(hostname));
if (argc >= 3)
strcpy(hostname, argv[2]);
hp = gethostbyname(hostname);
if (hp == NULL)
{
printf("\n%s: unknown host.\n", hostname);
exit(1);
}
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("CLIENT socket ");
exit(1);
}
printf("sock = %d\n",sock);
server.sin_family = AF_INET;
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_port = htons(port);
// Note that we need to create a client address.
// We didn't need to do this for connection oriented sockets
// The connect statement did all of this stuff for us automatically
client.sin_family = AF_INET;
client.sin_addr.s_addr = htonl(INADDR_ANY);
client.sin_port = htons(0); // pick any free port
// Note that we need to bind the client address to the socket
// similar to what we have always done for servers.
// Again, this detail was buried in the connect command for
// connection oriented socket programming.
if (bind(sock, (struct sockaddr *) &client, sizeof(client)) < 0)
{
perror("CLIENT bind ");
close(sock);
exit(2);
}
for (;;)
{
printf("Enter buffer to send\n");
str = fgets(buff, sizeof(buff), stdin);
if (str == NULL) break; // shouldn't happen
server_len = sizeof(server);
rc = sendto(sock, buff, strlen(buff), 0,
(struct sockaddr *)&server, server_len);
if (rc < 0)
{
perror("SERVER sendto ");
close(sock);
exit(5);
}
client_len = sizeof(client);
memset(buff, 0, BUFSIZE);
printf("msg sent and now waiting on recvfrom\n");
nread = recvfrom (sock, buff, BUFSIZE, 0,
(struct sockaddr *)&client, &client_len);
if (nread < 0)
{
perror("CLIENT recvfrom ");
close(sock);
exit(4);
}
buff[nread] = 0;
printf("received: %s\n", buff);
} // end of for loop
}
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define BUFSIZE 8000
main(int argc, char * argv[])
{
int sock, nread, rc, server_len, client_len;
int port;
struct sockaddr_in server, client;
char buff[BUFSIZE];
char hostname[64];
char *str;
struct hostent *hp;
struct in_addr HostAddr;
int nOpt = 1;
if (argc < 2)
{
printf("Useage: %s port [hostname]", argv[0]);
exit(0);
}
port = atoi(argv[1]);
gethostname(hostname, sizeof(hostname));
if (argc >= 3)
strcpy(hostname, argv[2]);
hp = gethostbyname(hostname);
if (hp == NULL)
{
printf("\n%s: unknown host.\n", hostname);
exit(1);
}
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("CLIENT socket ");
exit(1);
}
printf("sock = %d\n",sock);
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &nOpt, sizeof(int));
HostAddr = *((struct in_addr *) *(hp->h_addr_list));
HostAddr.s_addr |= 0xff000000; // Least significant byte for Intel CPU
// Some architectures require 0x000000ff
printf("Broadcast address = %s\n", inet_ntoa(HostAddr));
server.sin_family = AF_INET;
// memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_addr = HostAddr;
server.sin_port = htons(port);
// Note that we need to create a client address.
// We didn't need to do this for connection oriented sockets
// The connect statement did all of this stuff for us automatically
client.sin_family = AF_INET;
client.sin_addr.s_addr = htonl(INADDR_ANY);
client.sin_port = htons(0); // pick any free port
// Note that we need to bind the client address to the socket
// similar to what we have always done for servers.
// Again, this detail was buried in the connect command for
// connection oriented socket programming.
if (bind(sock, (struct sockaddr *) &client, sizeof(client)) < 0)
{
perror("CLIENT bind ");
close(sock);
exit(2);
}
for (;;)
{
printf("Enter buffer to send\n");
str = fgets(buff, sizeof(buff), stdin);
if (str == NULL) break; // shouldn't happen
server_len = sizeof(server);
rc = sendto(sock, buff, strlen(buff), 0,
(struct sockaddr *)&server, server_len);
if (rc < 0)
{
perror("SERVER sendto ");
close(sock);
exit(5);
}
client_len = sizeof(client);
memset(buff, 0, BUFSIZE);
printf("msg sent and now waiting on recvfrom\n");
nread = recvfrom (sock, buff, BUFSIZE, 0,
(struct sockaddr *)&client, &client_len);
if (nread < 0)
{
perror("CLIENT recvfrom ");
close(sock);
exit(4);
}
buff[nread] = 0;
printf("received: %s\n", buff);
} // end of for loop
}