-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwallserver.cpp
More file actions
183 lines (157 loc) · 5.85 KB
/
wallserver.cpp
File metadata and controls
183 lines (157 loc) · 5.85 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <queue>
#include <iostream>
#include <string>
#include <fcntl.h>
using namespace std;
void error(const char *msg)
{
perror(msg);
exit(1);
}
void printWall(int* socket, queue<string> que) {
string header = "Wall Contents\n";
string subHeader = "-------------\n";
string empty = "[NO MESSAGES – WALL EMPTY]\n\n";
write(*socket, header.c_str(), strlen(header.c_str()));
write(*socket, subHeader.c_str(), strlen(subHeader.c_str()));
if (que.empty())
write(*socket, empty.c_str(), strlen(empty.c_str()));
else {
while (!que.empty()) {
write(*socket, que.front().c_str(), strlen(que.front().c_str()));
write(*socket, "\n", 1);
que.pop();
}
write(*socket, "\n", 1);
}
}
void addToBoard(queue<string>* que, string message, int maxSize) {
if (que->size() >= maxSize) {
que->pop();
}
que->push(message);
}
int main(int argc, char *argv[])
{
// file descriptors
int sockfd;
int newsockfd = -1000;
int portno = 5514;
// sixe of the address of the client
socklen_t clilen;
// server reads character from socket connection into here
char buffer[256];
char name[256];
char message[256];
queue<string> bulletinBoard;
int maxLength = 20;
// struct containing an internet address. Defined in netinet/in.h
// server contains address of server, cli contains address of client
struct sockaddr_in serv_addr, cli_addr;
// number of characters read or written
int n;
// check if length or port were provided
if (argc >= 2)
maxLength = atoi(argv[1]);
if (argc >= 3)
portno = atoi(argv[2]);
// Creating a new socket. Returns an entry into the file descriptor
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
// Initializes serv_addr to all zeros
bzero((char *)&serv_addr, sizeof(serv_addr));
// Port number that the server will use to listen for connections
// Trivial
serv_addr.sin_family = AF_INET;
// IP address of the machine the server is running on
serv_addr.sin_addr.s_addr = INADDR_ANY;
// Port number must be converted to network of byte order
serv_addr.sin_port = htons(portno);
// Binding a socket to an address
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
// begins listening for connections
listen(sockfd, 5);
// Size of the client
clilen = sizeof(cli_addr);
// newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
// cout << "Client connected" << endl;
// printWall(&newsockfd, bulletinBoard);
while (1) {
// initializes buffer to be all zeros
bzero(buffer, 256);
bzero(name, 256);
bzero(message, 256);
// check if file server is conencted to the client or not
if (write(newsockfd, "Enter command: ", 15) < 0) {
// cout << "No client connection" << endl;
// file descriptor is invalid or closed
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
// cout << "Client connected" << endl;
if (newsockfd < 0)
error("ERROR on accept");
// Initial printing of the Wall
printWall(&newsockfd, bulletinBoard);
write(newsockfd, "Enter command: ", 15);
}
// read in data from client. Blocks until something is sent from client
n = read(newsockfd, buffer, 255);
if (n < 0)
error("ERROR reading from socket\r\n");
// printf("%s", buffer);
if (strncmp(buffer, "post", strlen("post")) == 0) {
write(newsockfd, "Enter Name: ", 12);
read(newsockfd, name, 256);
write(newsockfd, "Post [Max length ", 17);
// Get max length
int max = 80 - strlen(name) - 1;
write(newsockfd, to_string(max).c_str(), strlen(to_string(max).c_str()));
write(newsockfd, "]: ", 3);
read(newsockfd, message, 256);
if (strlen(message) > max + 1) {
write(newsockfd, "Error: message is too long!\n\n", 29);
} else {
write(newsockfd, "Successfully tagged the wall.\n\n", 31);
string n, m;
n = string(name);
m = string(message);
// Remove null terminators
n.pop_back();
m.pop_back();
string completeMessage = n + ": " + m;
addToBoard(&bulletinBoard, completeMessage, maxLength);
printWall(&newsockfd, bulletinBoard);
}
} else if (strncmp(buffer, "clear", strlen("clear")) == 0) {
// Empty board
while(!bulletinBoard.empty()) bulletinBoard.pop();
string output = "Wall cleared.\n\n";
write(newsockfd, output.c_str(), strlen(output.c_str()));
printWall(&newsockfd, bulletinBoard);
} else if (strncmp(buffer, "kill", strlen("kill")) == 0) {
string output = "Closing socket and terminating server. Bye!\n";
write(newsockfd, output.c_str(), strlen(output.c_str()));
break;
} else if (strncmp(buffer, "quit", strlen("quit")) == 0) {
string output = "Come back soon. Bye!\n";
write(newsockfd, output.c_str(), strlen(output.c_str()));
close(newsockfd);
} else {
write(newsockfd, "Command not recognized\n", 23);
}
}
// Close sockets
close(newsockfd);
close(sockfd);
return 0;
}