Appendix D
C Sockets Examples

File: Steve/Courses/2014/s2/its332/source.tex, r3463

This appendix includes example implementation of clients and servers that can exchange data across the Internet. They are implemented in C. There is a TCP version and a UDP version. The source code is quite old (there are newer, better constructs available), and may produce warnings when compiled, however it still executes as intended. The purpose of this code is to show a simple example of using sockets in C to create an Internet client/server application. If you want to create your own application, it is recommended you look for other (better) ways to implement in C.

The source code can be downloaded via http://ict.siit.tu.ac.th/~sgordon/netlab/source/.

D.1 TCP Sockets in C

D.1.1 Example Usage

On one computer compile the server and then start it. The server takes a port number as a command line argument:

$ gcc -o tcpserver socket_tcp_server.c 
$ ./tcpserver 5001

On another computer compile the client and then start it. The client takes the IP address of the server and the port number it uses as command line arguments:

$ gcc -o tcpclient socket_tcp_client.c 
$ ./tcpclient 10.10.6.210 5001

The client prompts for a message. Type in a message and press Enter. The result should be the message being displayed at the server and then the client printing “I got your message”. The client exits, but the server keeps running (other clients can connect).

An example on the client:

$ ./tcpclient 10.10.6.210 5001 
Please enter the message: Hello from Steve 
I got your message 
$

And on the server:

$ ./tcpserver 5001 
Here is the message: Hello from Steve

D.1.2 TCP Client

 
1/* ***************************************************************** 
2* ITS 332 Information Technology II (Networking) Lab 
3* Semester 2, 2010 
4* SIIT 
5* 
6* Client/Server Programming Lab 
7* File: client.c 
8* Date: 24 Jan 2007 
9* Version: 1.0 
10* 
11* Description: 
12* Client to demonstrate TCP sockets programming. You should read the 
13* server.c code as well. 
14* 
15* Usage: 
16* client server_ip_address server_port_number 
17* 
18* Acknowledgement: 
19* This code is based on the examples and descriptions from the 
20* Computer Science Department, Rensselaer Polytechnic Institute at: 
21* http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html 
22* 
23* ***************************************************************** */ 
24 
25#include <stdio.h> 
26#include <string.h> 
27#include <stdlib.h> 
28#include <sys/types.h> 
29#include <sys/socket.h> 
30#include <netinet/in.h> 
31#include <netdb.h> 
32 
33/* ================================================================= */ 
34/* error: display an error message and exit                */ 
35/* ================================================================= */ 
36void error(char *msg) 
37{ 
38   perror(msg); 
39   exit(0); 
40} 
41 
42/* ================================================================= */ 
43/* main: connect to server, prompt for a message, send the message, */ 
44/* receive the ack from server and then exit               */ 
45/* ================================================================= */ 
46int main(int argc, char *argv[]) 
47{ 
48   /* socket file descriptor, port number of server, and number of bytes */ 
49   int sockfd, portno, n; 
50   struct sockaddr_in serv_addr; /* server address */ 
51   /* The hostent structure defines a host computer on the Internet. It 
52     contains field which describe the host name, aliases for the name, 
53     address type and actual address (e.g. IP address) */ 
54   struct hostent *server; 
55   char buffer[256]; 
56 
57   /* The user must enter two parameters on the command line: 
58      - server host name or IP address 
59      - port number used by server */ 
60   if (argc < 3) { 
61     fprintf(stderr,"usage%shostnameport\n", argv[0]); 
62     exit(0); 
63   } 
64   /* Get the port number for server entered by user */ 
65   portno = atoi(argv[2]); 
66 
67   /* Create an Internet stream (TCP) socket */ 
68   sockfd = socket(AF_INET, SOCK_STREAM, 0); 
69   if (sockfd < 0) 
70      error("ERRORopeningsocket"); 
71 
72   /* The gethostbyname() system call uses DNS to determine the IP 
73     address of the host */ 
74   server = gethostbyname(argv[1]); 
75   if (server == NULL) { 
76      fprintf(stderr,"ERROR,nosuchhost\n"); 
77      exit(0); 
78   } 
79 
80   /* Set the server address to all zeros */ 
81   bzero((char *) &serv_addr, sizeof(serv_addr)); 
82   serv_addr.sin_family = AF_INET; /* Internet family of protocols */ 
83 
84   /* Copy server address obtained from gethostbyname to our 
85     serv_addr structure */ 
86   bcopy((char *)server->h_addr, 
87      (char *)&serv_addr.sin_addr.s_addr, 
88      server->h_length); 
89 
90   /* Convert port number to network byte order */ 
91   serv_addr.sin_port = htons(portno); 
92 
93   /* The connect() system call establishes a connection to the server. The 
94     three parameters are: 
95      - socket file descriptor 
96      - address of server 
97      - size of the servers address */ 
98   if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
99      error("ERRORconnecting"); 
100 
101   /* Once connected, the client prompts for a message, and the users 
102     input message is obtained with fgets() and written to the socket 
103     using write(). */ 
104   printf("Pleaseenterthemessage:"); 
105   bzero(buffer,256); 
106   fgets(buffer,255,stdin); 
107   n = write(sockfd,buffer,strlen(buffer)); 
108   if (n < 0) 
109      error("ERRORwritingtosocket"); 
110 
111   /* Zero a buffer and then read from the socket */ 
112   bzero(buffer,256); 
113   n = read(sockfd,buffer,255); 
114   if (n < 0) 
115      error("ERRORreadingfromsocket"); 
116 
117   /* Display the received message and then quit the program */ 
118   printf("%s\n",buffer); 
119   return 0; 
120}

D.1.3 TCP Server

 
1/* ***************************************************************** 
2* ITS 332 Information Technology II (Networking) Lab 
3* Semester 2, 2010 
4* SIIT 
5* 
6* Client/Server Programming Lab 
7* File: server.c 
8* Date: 24 Jan 2007 
9* Version: 1.0 
10* 
11* Description: 
12* Server to demonstrate TCP sockets programming 
13* 
14* Usage: 
15* server server_port_number 
16* 
17* Acknowledgement: 
18* This code is based on the examples and descriptions from the 
19* Computer Science Department, Rensselaer Polytechnic Institute at: 
20* http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html 
21* 
22* ***************************************************************** */ 
23 
24#include <stdio.h> 
25#include <string.h> 
26#include <stdlib.h> 
27#include <sys/types.h> 
28#include <sys/socket.h> 
29#include <netinet/in.h> 
30 
31/* ================================================================= */ 
32/* Function Prototypes                                 */ 
33/* ================================================================= */ 
34void dostuff(int); 
35 
36/* ================================================================= */ 
37/* error: display an error message and exit                */ 
38/* ================================================================= */ 
39void error(char *msg) 
40{ 
41   perror(msg); 
42   exit(1); 
43} 
44 
45/* ================================================================= */ 
46/* main: listen for connections, and create new process for each */ 
47/* connection. Receive the message from client and acknowledge. */ 
48/* ================================================================= */ 
49int main(int argc, char *argv[]) 
50{ 
51   /* file descriptors that contain values return from socket and 
52   and accept system calls */ 
53   int sockfd, newsockfd; 
54   int portno; /* port number on which server accepts connections */ 
55   int pid; /* process ID for newly created child process */ 
56   /* sockaddr_in is a structure containing an IP address - it is 
57      defined in netinet/in.h */ 
58   struct sockaddr_in serv_addr, cli_addr; 
59   size_t clilen; /* size of the address of the client */ 
60 
61   /* The user must pass the port number that the server listens on 
62      as a command line parameter (otherwise error) */ 
63   if (argc < 2) { 
64      fprintf(stderr,"ERROR,noportprovided\n"); 
65      exit(1); 
66   } 
67 
68   /* First we must create a socket using the socket() system call. 
69      The three parameters are: 
70      - address domain of the socket. It may be an Unix socket, an 
71        Internet socket or others. We use the Internet socket which 
72        is defined by the constant AF_INET 
73      - socket type. Stream (TCP), or Datagram (UDP, SOCK_DGRAM) or 
74        a raw socket (for accessing IP directly). 
75      - the protocol. 0 means the operating system will choose the 
76        most appropriate protocol: TCP for stream and UDP for 
77        datagram. 
78      The call to socket returns a file descriptor (or -1 if it fails) */ 
79   sockfd = socket(AF_INET, SOCK_STREAM, 0); 
80   if (sockfd < 0) 
81      error("ERRORopeningsocket"); 
82 
83   /* bzero sets all values in a buffer to 0. Here we set the server 
84      address to 0 */ 
85   bzero((char *) &serv_addr, sizeof(serv_addr)); 
86 
87   /* Get the port number that the user entered via command line */ 
88   portno = atoi(argv[1]); 
89 
90   /* Now we set the server address in the structure serv_addr */ 
91   /* Note that INADDR_ANY is a constant that refers to the IP 
92      address of the machine the server is running on. */ 
93   /* Note that the port number must be specified in network byte order. 
94      Different computer systems represents bytes in different order: 
95      big endian - most significant bit of byte is first 
96      little endian - least significant bit of byte is first 
97      For this reason, everything must be converted to network byte 
98      order (which is big endian). htons does this conversion. */ 
99   serv_addr.sin_family = AF_INET; /* Protocol family: Internet */ 
100   serv_addr.sin_addr.s_addr = INADDR_ANY; /* Server address */ 
101   serv_addr.sin_port = htons(portno); /* Port number */ 
102 
103   /* The bind() system call binds a socket to an address. This 
104      may fail if for example the port number is already being 
105      used on this machine. */ 
106   if (bind(sockfd, (struct sockaddr *) &serv_addr, 
107          sizeof(serv_addr)) < 0) 
108          error("ERRORonbinding"); 
109 
110   /* The listen() system call tells the process to listen on the 
111      socket for connections. The first parameter is a file descriptor 
112      for the socket and the second parameter is the number of 
113      connections that can be queued while the process is handling this 
114      connection. 5 is a reasonable value for most systems */ 
115   listen(sockfd,5); 
116   clilen = sizeof(cli_addr); 
117 
118   /* Now we enter an infinite loop, waiting for connections from clients. 
119      When a connection is established, we will create a new child process 
120      using fork(). The child process will handle the data transfer with 
121      the client. The parent process will wait for another connection. */ 
122   while (1) { 
123   /* The accept() system call causes the process to block until a 
124         client connects with the server. The process will wake up once 
125         the connection has been established (e.g. TCP handshake). 
126         The parameters to accept are: 
127         - the file descriptor of the socket we are waiting on 
128         - a structure to store the address of the client that connects 
129         - a variable to store the length of the client address 
130         It returns a new file descriptor for the socket, and all 
131         communication is now done with this new descriptor. */ 
132      newsockfd = accept(sockfd, 
133           (struct sockaddr *) &cli_addr, &clilen); 
134      if (newsockfd < 0) 
135         error("ERRORonaccept"); 
136 
137   /* Create child process to handle the data transfer */ 
138      pid = fork(); 
139      if (pid < 0) 
140         error("ERRORonfork"); 
141      /* The process ID in the child process will be 0. Hence the child 
142         process will close the old socket file descriptor and then call 
143         dostuff() to perform the interactions with the client. When 
144         complete, the child process will exit. */ 
145      if (pid == 0) { 
146         close(sockfd); 
147         dostuff(newsockfd); 
148         exit(0); 
149      } 
150   /* This is called by the parent process only. It closes the 
151         new socket file descriptor, which is not needed by the parent */ 
152      else close(newsockfd); 
153   } /* end of while */ 
154   return 0; /* we never get here because we are in infinite loop */ 
155} 
156 
157/* ================================================================= */ 
158/* dostuff: exchange some messages between client and server. There */ 
159/* is a separate instance of this function for each connection. */ 
160/* ================================================================= */ 
161void dostuff (int sock) 
162{ 
163  int n; 
164  char buffer[256]; 
165 
166  /* Set a 256 byte buffer to all zeros */ 
167  bzero(buffer,256); 
168 
169  /* Read from the socket. This will block until there is something for 
170    it to read in the socket (i.e. after the client has executed a 
171    write()). It will read either the total number of characters in the 
172    socket or 255, whichever is less, and return the number of characters 
173    read. */ 
174  n = read(sock,buffer,255); 
175  if (n < 0) error("ERRORreadingfromsocket"); 
176 
177  /* Display the message that was received */ 
178  printf("Hereisthemessage:%s\n",buffer); 
179 
180  /* Write a message to the socket. The third parameter is the size of 
181    the message */ 
182  n = write(sock,"Igotyourmessage",18); 
183  if (n < 0) error("ERRORwritingtosocket"); 
184}

D.2 UDP Sockets in C

D.2.1 Example Usage

On one computer compile the server and then start it. The server takes a port number as a command line argument:

$ gcc -o udpserver socket_udp_server.c 
$ ./udpserver 5001

On another computer compile the client and then start it. The client takes the IP address of the server and the port number it uses as command line arguments:

$ gcc -o udpclient socket_udp_client.c 
$ ./udpclient 10.10.6.210 5001

The client prompts for a message. Type in a message and press Enter. The result should be the message being displayed at the server and then the client printing “Got your message”. The client exits, but the server keeps running (other clients can connect).

An example on the client:

$ ./udpclient 10.10.6.210 5002 
Please enter the message: a udp test 
Got an ack: Got your message 
$

And on the server:

$ ./udpserver 5002 
Received a datagram: a udp test

D.2.2 UDP Client

 
1/* ***************************************************************** 
2* ITS 332 Information Technology II (Networking) Lab 
3* Semester 2, 2006 
4* SIIT 
5* 
6* Client/Server Programming Lab 
7* File: client_idp.c 
8* Date: 29 Jan 2007 
9* Version: 1.0 
10* 
11* Description: 
12* Client to demonstrate UDP sockets programming. You should read the 
13* server_udp.c code as well. 
14* 
15* Usage: 
16* client server_ip_address server_port_number 
17* 
18* Acknowledgement: 
19* This code is based on the examples and descriptions from the 
20* Computer Science Department, Rensselaer Polytechnic Institute at: 
21* http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html 
22* 
23* ***************************************************************** */ 
24 
25#include <stdio.h> 
26#include <string.h> 
27#include <stdlib.h> 
28#include <sys/types.h> 
29#include <sys/socket.h> 
30#include <netinet/in.h> 
31#include <arpa/inet.h> 
32#include <netdb.h> 
33 
34/* ================================================================= */ 
35/* error: display an error message and exit                */ 
36/* ================================================================= */ 
37void error(char *msg) 
38{ 
39   perror(msg); 
40   exit(0); 
41} 
42 
43/* ================================================================= */ 
44/* main: create socket and send message to server           */ 
45/* ================================================================= */ 
46int main(int argc, char *argv[]) 
47{ 
48  int sock, n; 
49  struct sockaddr_in server, from; 
50  struct hostent *hp; 
51  char buffer[256]; 
52  size_t length; 
53 
54  /* User must input server and port number */ 
55  if (argc != 3) { printf("Usage:serverport\n"); 
56               exit(1); 
57  } 
58 
59  /* Create a Datagram (UDP) socket */ 
60  sock= socket(AF_INET, SOCK_DGRAM, 0); 
61  if (sock < 0) error("socket"); 
62 
63  server.sin_family = AF_INET; 
64 
65  /* Get the IP address for destination server */ 
66  hp = gethostbyname(argv[1]); 
67  if (hp==0) error("Unknownhost"); 
68 
69  /* Set the server address and port */ 
70  bcopy((char *)hp->h_addr, 
71      (char *)&server.sin_addr, 
72      hp->h_length); 
73  server.sin_port = htons(atoi(argv[2])); 
74 
75  length=sizeof(struct sockaddr_in); 
76 
77  /* Prompt for message from user */ 
78  printf("Pleaseenterthemessage:"); 
79  bzero(buffer,256); 
80  fgets(buffer,255,stdin); 
81 
82  /* Send message to socket (server) */ 
83  n=sendto(sock,buffer, 
84         strlen(buffer),0,(struct sockaddr *) &server,length); 
85  if (n < 0) error("Sendto"); 
86 
87  /* Receive response from server */ 
88  n = recvfrom(sock,buffer,256,0,(struct sockaddr *) &from, &length); 
89  if (n < 0) error("recvfrom"); 
90 
91  /* Display response to user */ 
92  write(1,"Gotanack:",12); 
93  write(1,buffer,n); 
94}

D.2.3 UDP Server

 
1/* ***************************************************************** 
2* ITS 332 Information Technology II (Networking) Lab 
3* Semester 2, 2006 
4* SIIT 
5* 
6* Client/Server Programming Lab 
7* File: server_udp.c 
8* Date: 29 Jan 2007 
9* Version: 1.0 
10* 
11* Description: 
12* Server to demonstrate UDP sockets programming 
13* 
14* Usage: 
15* server server_port_number 
16* 
17* Acknowledgement: 
18* This code is based on the examples and descriptions from the 
19* Computer Science Department, Rensselaer Polytechnic Institute at: 
20* http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html 
21* 
22* ***************************************************************** */ 
23 
24#include <stdio.h> 
25#include <string.h> 
26#include <stdlib.h> 
27#include <sys/types.h> 
28#include <sys/socket.h> 
29#include <netinet/in.h> 
30#include <netdb.h> 
31 
32/* ================================================================= */ 
33/* error: display an error message and exit                */ 
34/* ================================================================= */ 
35void error(char *msg) 
36{ 
37   perror(msg); 
38   exit(0); 
39} 
40 
41/* ================================================================= */ 
42/* main: create socket and receive/send to socket           */ 
43/* ================================================================= */ 
44int main(int argc, char *argv[]) 
45{ 
46  int sock, length, n; 
47  struct sockaddr_in server; /* server address structure */ 
48  struct sockaddr_in from; /* source address structure */ 
49  char buf[1024]; 
50  size_t fromlen; 
51 
52  /* Port number must be passed as parameter */ 
53  if (argc < 2) { 
54    fprintf(stderr, "ERROR,noportprovided\n"); 
55    exit(0); 
56  } 
57 
58  /* Create a Datagram (UDP) socket */ 
59  sock=socket(AF_INET, SOCK_DGRAM, 0); 
60  if (sock < 0) error("Openingsocket"); 
61 
62  length = sizeof(server); 
63  bzero(&server,length); 
64 
65  /* Set the server address */ 
66  server.sin_family=AF_INET; 
67  server.sin_addr.s_addr=INADDR_ANY; 
68  server.sin_port=htons(atoi(argv[1])); 
69 
70  /* Bind the socket to the address */ 
71  if (bind(sock,(struct sockaddr *)&server,length)<0) 
72     error("binding"); 
73 
74  fromlen = sizeof(struct sockaddr_in); 
75  /* Infinite loop, receiving data and sending response */ 
76  while (1) { 
77     /* Receive data from socket. Parameters are: 
78        - server socket 
79        - buffer to read data into 
80        - maximum buffer size 
81        - flags to control the receive operation 
82        - structure to store source address 
83        - source address length 
84        */ 
85     n = recvfrom(sock,buf,1024,0,(struct sockaddr *)&from,&fromlen); 
86     if (n < 0) error("recvfrom"); 
87     write(1,"Receivedadatagram:",21); 
88     write(1,buf,n); 
89     /* Write data to socket. Parameters are: 
90       - server socket 
91       - data to write 
92       - length of data 
93       - flags to control send operation 
94       - destination address 
95       - length of destination address 
96       */ 
97     n = sendto(sock,"Gotyourmessage\n",17, 
98             0,(struct sockaddr *)&from,fromlen); 
99     if (n < 0) error("sendto"); 
100  } 
101}