You are on page 1of 3

Echo Server in C 1

1 /* Echo Server - Defined in RFC-862 */


2
3 #include <stdio.h>
4 #include <sys/io.h>
5 #include <netinet/in.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <netdb.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <pthread.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/ioctl.h>
16
17 #define MAX_BUFSIZE 100
18
19 struct _conn
20 {
21 pthread_t thread;
22 struct sockaddr_in *cli;
23 int connfd;
24 };
25
26 typedef struct _conn conn;
27 typedef struct sockaddr SA;
28
29 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
30
31 void safe_printf(char *fmt, int arg1, int arg2)
32 {
33 pthread_mutex_lock( &mutex1 );
34 printf(fmt, arg1, arg2); // Critical Section.
35 pthread_mutex_unlock( &mutex1 );
36 }
37
38 void CloseConnection(conn *c)
39 {
40 char ip[16];
41 inet_ntop(AF_INET, &(c->cli->sin_addr.s_addr), ip, INET_ADDRSTRLEN);
42 safe_printf("%s (Port %d) disconnected.\n", (int)ip, c->cli->sin_port);
43 close(c->connfd);
44 free(c->cli);
45 free(c);
46 }
47
48 void *HandleClient(void *arg)
49 {
50 char buf[MAX_BUFSIZE], ip[16];
51 int n;
52 conn *c = (conn *)arg;
53 int connfd=c->connfd;
54 inet_ntop(AF_INET, &(c->cli->sin_addr.s_addr), ip, INET_ADDRSTRLEN);
55 safe_printf("%s (Port %d) connected.\n", (int)ip, c->cli->sin_port);
56
Shree Motilal Kanhaiyalal Fomra Institute of Technology
Echo Server in C 2

57 while(1)
58 {
59 bzero(buf, MAX_BUFSIZE);
60 if(!read(connfd, buf, sizeof(buf)))
61 {
62 // There are many reasons for 'read' to fail
63 // So better attempt to close the socket.
64 CloseConnection(c);
65 return NULL;
66 }
67 write(connfd, buf, sizeof(buf));
68 }
69 return NULL;
70 }
71
72
73 int main(int argc, char *argv[])
74 {
75 // IANA has assigned port 7 for echo service.
76 // But 0-1023 are "Well-Known", and 1024–49151 are "Registered".
77 // Moreover, port 7 may require root privilege (sudo).
78 // So, consider changing port number if socket fails to bind.
79 int sockfd, connfd, port=7;
80 struct sockaddr_in serveraddr, *cli;
81 conn *c;
82 socklen_t len;
83 if(argc>=2)
84 {
85 port = atoi(argv[1]);
86 if(port<0)
87 port=7;
88 }
89 sockfd=socket(AF_INET, SOCK_STREAM, 0);
90 if(sockfd==-1)
91 {
92 safe_printf("Socket creation failed\n", 0, 0);
93 exit(0);
94 }
95 safe_printf("Socket successfully created\n", 0, 0);
96
97 bzero(&serveraddr, sizeof(serveraddr));
98 serveraddr.sin_family = AF_INET;
99 serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
100 serveraddr.sin_port = htons(port);
101 if(bind(sockfd, (SA *)&serveraddr, sizeof(serveraddr)))
102 {
103 safe_printf("Failed to bind socket (Tried @ port %d).\n", port, 0);
104 exit(0);
105 }
106 safe_printf("Socket successfully bound...\n", 0, 0);
107
108 if(listen(sockfd, 5))
109 {
110 safe_printf("Listen failed\n", 0, 0);
111 exit(0);
112 }
Shree Motilal Kanhaiyalal Fomra Institute of Technology
Echo Server in C 3

113 safe_printf("Server listening at port %d...\n", port, 0);


114
115 len=sizeof(struct sockaddr_in);
116
117 while(1)
118 {
119 cli = (struct sockaddr_in *)malloc(len);
120 connfd=accept(sockfd, (SA *)cli, &len);
121 if(connfd<0)
122 {
123 safe_printf("Failed to accept a client. Terminating server...\n", 0, 0);
124 exit(0);
125 }
126 safe_printf("Server accepted client...\n" , 0, 0);
127 c = (conn *)malloc(sizeof(conn));
128 c->connfd = connfd;
129 c->cli = cli;
130 pthread_create(&(c->thread), NULL, &HandleClient, (void *)(c));
131 }
132 close(sockfd);
133 }
134
135 /*
136 SERVER OUTPUT (SAMPLE):
137 kaushik@kaushik-desktop:~/netlab$ gcc ex03.c -pthread -o echoserver
138 kaushik@kaushik-desktop:~/netlab$ ./echoserver
139 Socket successfully created
140 Failed to bind socket (Tried @ port 7).
141 kaushik@kaushik-desktop:~/netlab$ sudo ./echoserver
142 Socket successfully created
143 Socket successfully bound...
144 Server listening at port 7...
145 Server accepted client...
146 127.0.0.1 (Port 44965) connected.
147 Server accepted client...
148 127.0.0.1 (Port 45221) connected.
149 Server accepted client...
150 127.0.0.1 (Port 45477) connected.
151 127.0.0.1 (Port 45221) disconnected.
152 127.0.0.1 (Port 45477) disconnected.
153 127.0.0.1 (Port 44965) disconnected.
154 */

Shree Motilal Kanhaiyalal Fomra Institute of Technology

You might also like