-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.c
155 lines (132 loc) · 5.38 KB
/
server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // close socket
#include <errno.h> // error codes
#include <stdbool.h> // boolean types
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <string.h>
#include <signal.h> // for interrupt signal handler
#include <assert.h> // assert()
#define PORT 9002
#define BUFFER_SIZE 1024
int server_socket; // global variable in order to be handled after SIGINT
void handle_signal(int sig); // interrupt signal handler
char *readHTML(char *filename); // utility function to read HTML file
int main(int argc, char *argv[])
{
// create the server socket
puts("Creating socket ...");
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("Socket failed: ");
printf("Error code: %d\n", errno);
return EXIT_FAILURE;
}
puts("Socket created!");
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
//server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
// bind the socket to our specified IP and port
puts("Binding socket ...");
if ((bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address))) < 0) {
perror("Bind failed");
printf("Error code: %d\n", errno);
return EXIT_FAILURE;
}
puts("Binding done!");
signal(SIGINT, handle_signal);
while (true) { // continuously listen for connections
puts("Waiting for incoming requests... (press Ctrl+C to quit)\n");
if ((listen(server_socket, 5)) < 0) {
perror("Listen failed");
printf("Error code: %d\n", errno);
}
// accept the connection
int client_socket; // client socket
struct sockaddr_in *client_address=NULL; // client address pointer initialized as null pointer
if ((client_socket = accept(server_socket, (struct sockaddr *)client_address, (socklen_t*)sizeof(client_address))) < 0) {
perror("Accept failed");
printf("Error code: %d\n", errno);
return EXIT_FAILURE;
}
puts("Request accepted!\n");
/* --------------- Displays client data --------------- */
// Display client IP address
struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&client_address;
struct in_addr ipAddr = pV4Addr->sin_addr;
char client_ip_address[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipAddr, client_ip_address, INET_ADDRSTRLEN);
printf("Client IP address: %s\n\n", client_ip_address);
char client_message[BUFFER_SIZE];
if ((recv(client_socket, &client_message, sizeof(client_message), 0)) < 0) {
perror("Receive error:");
printf("Error code: %d\n", errno);
return EXIT_FAILURE;
}
// print the client request
printf("Data sent by the client:\n\n%s", client_message);
char client_header[] = "GET / HTTP/1.1"; // request header to be handled
char *request = strstr(client_message, client_header); // search within client message for header
memset(client_message, 0, sizeof(client_message)); // sets client message to null pointer
/* --------------- Sending data --------------- */
// define response date
time_t t;
time(&t);
char *current_date;
current_date = ctime(&t);
current_date[strcspn(current_date, "\n")] = 0; // removes newline for correct parsing
char server_message[BUFFER_SIZE];
char *content;
if (request == NULL) {
// define response content (HTML)
content = "<html>\n<head>\n<title>Error 404</title>\n</head>\n<body>\n<h1>Error 404</h1>\n<p>Error 404 - Not Found</p>\n</body>\n</html>";
// define response headers
sprintf(server_message, "HTTP/1.0 404 Not Found\nDate: %s\nContent-Type: text/html\nContent-Length: %ld\n\n%s", current_date, strlen(content), content);
// sends the message
send(client_socket, &server_message, sizeof(server_message), 0);
}
else {
// define response content (HTML)
content = readHTML("static/index.html");
// define response headers
sprintf(server_message, "HTTP/1.0 200 OK\nDate: %s\nContent-Type: text/html\nContent-Length: %ld\n\n%s", current_date, strlen(content), content);
// sends the message
send(client_socket, &server_message, sizeof(server_message), 0);
}
memset(server_message, 0, sizeof(server_message)); // sets server data to null pointer (cleanup)
}
return 0;
}
void handle_signal(int sig)
{
printf("\nCaught interrupt signal %d\n", sig);
// closes the socket
puts("Closing socket ...");
if (close(server_socket) == 0) {
puts("Socket closed!");
exit(0);
}
else {
perror("An error occurred while closing the socket: ");
printf("Error code: %d\n", errno);
exit(1);
}
}
char *readHTML(char *filename) {
FILE *f = fopen(filename, "rt");
assert(f);
fseek(f, 0, SEEK_END);
long length = ftell(f);
fseek(f, 0, SEEK_SET);
char *buffer = (char *) malloc(length + 1);
buffer[length] = '\0';
fread(buffer, 1, length, f);
fclose(f);
return buffer;
}