Example codes: BSD Sockets

Simple TCP Client

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_BUF 100

int main(int argc, char* argv[])
{
  int sockd;
  int count;
  struct sockaddr_in serv_name;
  char buf[MAX_BUF];
  int status;

  if (argc < 3)
  {
    fprintf(stderr, "Usage: %s ip_address port_number\n", argv[0]);
    exit(1);
  }
  /* create a socket */
  sockd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockd == -1)
  {
    perror("Socket creation");
    exit(1);
  }

  /* server address */ 
  serv_name.sin_family = AF_INET;
  inet_aton(argv[1], &serv_name.sin_addr);
  serv_name.sin_port = htons(atoi(argv[2]));

  /* connect to the server */
  status = connect(sockd, (struct sockaddr*)&serv_name, sizeof(serv_name));
  if (status == -1)
  {
    perror("Connection error");
    exit(1);
  }

  count = read(sockd, buf, MAX_BUF);
  write(1, buf, count);

  close(sockd);
  return 0;
}

Source code: client-tcp-simple.c.

Simple TCP Server

#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
  int sockd, sockd2;
  int addrlen;
  struct sockaddr_in my_name, peer_name;
  int status;

  /* create a socket */
  sockd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockd == -1)
  {
    perror("Socket creation error");
    exit(1);
  }

  if (argc < 2)
  {
    fprintf(stderr, "Usage: %s port_number\n", argv[0]);
    exit(1);
  }

  /* server address  */
  my_name.sin_family = AF_INET;
  my_name.sin_addr.s_addr = INADDR_ANY;
  my_name.sin_port = htons(atoi(argv[1]));

  status = bind(sockd, (struct sockaddr*)&my_name, sizeof(my_name));
  if (status == -1)
  {
    perror("Binding error");
    exit(1);
  }

  status = listen(sockd, 5);
  if (status == -1)
  {
    perror("Listening error");
    exit(1);
  }

  for(;;)
  {
    /* wait for a connection */
    addrlen = sizeof(peer_name);
    sockd2 = accept(sockd, (struct sockaddr*)&peer_name, &addrlen);
    if (sockd2 == -1)
    {
      perror("Wrong connection");
      exit(1);
    }
    write(sockd2, "Hello!\n", 7);
    close(sockd2);
  }
  return 0;
}

Source code: server-tcp-simple.c.

Reusing previously bound addresses:

int val = 1;
...
setsockopt(sockd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));

File transfer: client side

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#define MAX_BUF 1024
#define S_PORT  6398

int main(int argc, char* argv[])
{
  int sockd;
  int count;
  struct sockaddr_in serv_name;
  char buf[MAX_BUF];
  int status;

  if (argc < 3)
  {
    fprintf(stderr, "Usage: %s ip_address filename\n", argv[0]);
    exit(1);
  }
  /* create a socket */
  sockd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockd == -1)
  {
    perror("Socket creation");
    exit(1);
  }

  /* server address */ 
  serv_name.sin_family = AF_INET;
  inet_aton(argv[1], &serv_name.sin_addr);
  serv_name.sin_port = htons(S_PORT);

  /* connect to the server */
  status = connect(sockd, (struct sockaddr*)&serv_name, sizeof(serv_name));
  if (status == -1)
  {
    perror("Connection error");
    exit(1);
  }

  write(sockd, argv[2], strlen(argv[2])+1);
  shutdown(sockd, 1);
  while ((count = read(sockd, buf, MAX_BUF))>0)
  {
    write(1, buf, count);
  }
  if (count == -1)
  {
    perror("Read error");
    exit(1);
  }

  close(sockd);
  return 0;
}

Source code: client-tcp-file.c.

File transfer: server side

#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>

#define MAX_BUF 1024
#define S_PORT  6398

int main()
{
  int sockd,sockd2;
  int addrlen;
  struct sockaddr_in my_name, peer_name;
  int status;

  /* create a socket */
  sockd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockd == -1)
  {
    perror("Tworzenie gniazda");
    exit(1);
  }

  /* socket binding */
  my_name.sin_family = AF_INET;
  my_name.sin_addr.s_addr = INADDR_ANY;
  my_name.sin_port = htons(S_PORT);

  status = bind(sockd, (struct sockaddr*)&my_name, sizeof(my_name));
  if (status == -1)
  {
    perror("Binding");
    exit(1);
  }

  status = listen(sockd, 5);
  if (status == -1){
    perror("Listening");
    exit(1);
  }

  for(;;)
  {
    int fd;
    int i, count_r, count_w;
    char* bufptr;
    char buf[MAX_BUF];
    char filename[MAX_BUF];

    /* wait for an incoming connection */
    addrlen = sizeof(peer_name);
    sockd2 = accept(sockd, (struct sockaddr*)&peer_name, &addrlen);
    if (sockd2 == -1)
    {
      perror("Connection accept");
      exit(1);
    }

    i = 0;
    if ((count_r = read(sockd2, filename + i, MAX_BUF))>0)
    {
      i += count_r;
    }
    filename[i-1] = '\0';
    if (count_r == -1){
      perror("Read error");
      exit(1);
    }
    printf("Trying to read file %s\n", filename);

    fd = open(filename, O_RDONLY); 
    if (fd == -1)
    {
      perror("File open error");
      exit(1);
    }
    while((count_r = read(fd, buf, MAX_BUF))>0)
    {
      count_w = 0;
      bufptr = buf;
      while (count_w < count_r)
      {
        count_r -= count_w;
        bufptr += count_w;
        count_w = write(sockd2, bufptr, count_r);
        if (count_w == -1) 
        {
          perror("Socket read error");
          exit(1);
        }
      }
    }
    close(fd);
    close(sockd2);
  }
  return 0;
}

Source code: server-tcp-file.c.

Simple UDP Client

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_BUF 100

int main(int argc, char* argv[])
{
  int sockd;
  struct sockaddr_in my_addr, srv_addr;
  char buf[MAX_BUF];
  int count;
  int addrlen;

  if (argc < 3)
  {
    fprintf(stderr, "Usage: %s ip_address port_number\n", argv[0]);
    exit(1);
  }
  /* create a socket */
  sockd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sockd == -1)
  {
    perror("Socket creation error");
    exit(1);
  }

  /* client address */
  my_addr.sin_family = AF_INET;
  my_addr.sin_addr.s_addr = INADDR_ANY;
  my_addr.sin_port = 0;

  bind(sockd, (struct sockaddr*)&my_addr, sizeof(my_addr));

  strcpy(buf, "Hello world\n");

  /* server address */ 
  srv_addr.sin_family = AF_INET;
  inet_aton(argv[1], &srv_addr.sin_addr);
  srv_addr.sin_port = htons(atoi(argv[2]));

  sendto(sockd, buf, strlen(buf)+1, 0, 
      (struct sockaddr*)&srv_addr, sizeof(srv_addr));

  addrlen = sizeof(srv_addr);
  count = recvfrom(sockd, buf, MAX_BUF, 0, 
      (struct sockaddr*)&srv_addr, &addrlen);
  write(1, buf, count);

  close(sockd);
  return 0;
}

Source code: client-udp-simple.c.

Broadcasting requires setting an additional socket option:

int val = 1;
...
setsockopt(sockd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val));

Simple UDP Server

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_BUF 1024

int main(int argc, char* argv[])
{
  int sockd;
  struct sockaddr_in my_name, cli_name;
  char buf[MAX_BUF];
  int status;
  int addrlen;

  if (argc < 2)
  {
    fprintf(stderr, "Usage: %s port_number\n", argv[0]);
    exit(1);
  }
  /* create a socket */
  sockd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sockd == -1)
  {
    perror("Socket creation error");
    exit(1);
  }

  /* server address */
  my_name.sin_family = AF_INET;
  my_name.sin_addr.s_addr = INADDR_ANY;
  my_name.sin_port = htons(atoi(argv[1]));

  status = bind(sockd, (struct sockaddr*)&my_name, sizeof(my_name));

  addrlen = sizeof(cli_name);
  status = recvfrom(sockd, buf, MAX_BUF, 0,
      (struct sockaddr*)&cli_name, &addrlen);

  printf("%s", buf);
  strcat(buf, "OK!\n");

  status = sendto(sockd, buf, strlen(buf)+1, 0,
      (struct sockaddr*)&cli_name, sizeof(cli_name));

  close(sockd);
  return 0;
}

Source code: server-udp-simple.c.