-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathserver.cc
139 lines (120 loc) · 3.48 KB
/
server.cc
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
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
#include <fstream>
#include "messages.pb.h"
#define PORT 9999
using namespace std;
// This function reads a serialized protobuf msg from socket
void read(int new_socket, string& msg);
// Iterates though all people in the AddressBook and prints info about them.
void list_people(const Messages::AddressBook& address_book);
// main
int main(int argc, char const *argv[])
{
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
cout << "server start listening on "<< PORT <<"...\n";
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
while ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen)))
{
if(new_socket < 0) {
perror("accept");
exit(EXIT_FAILURE);
} else
{
string message;
read(new_socket, message);
Messages::AddressBook address_book;
if (!address_book.ParseFromString(message)) {
cerr << "Failed to parse address book." << endl;
return -1;
}
list_people(address_book);
}
}
return 0;
}
void read(int new_socket, string& msg) {
int valread;
char buffer_header[sizeof(size_t)] = {0};
valread = read( new_socket , buffer_header, sizeof(size_t));
size_t msg_size;
memcpy(&msg_size, buffer_header, sizeof(size_t));
char* buffer_msg = (char*)malloc(msg_size*sizeof(char));
memset(buffer_msg, '\0', sizeof(char)*msg_size);
int length = 0;
for(length = 0; msg_size != 0; length += valread) {
valread = read( new_socket , buffer_msg+length, msg_size);
msg_size -= valread;
}
msg = std::string(buffer_msg, length);
free(buffer_msg);
}
void list_people(const Messages::AddressBook& address_book) {
for (int i = 0; i < address_book.people_size(); i++) {
const Messages::Person& person = address_book.people(i);
cout << "Person ID: " << person.id() << endl;
cout << " Name: " << person.name() << endl;
if (person.email() != "") {
cout << " E-mail address: " << person.email() << endl;
}
for (int j = 0; j < person.phones_size(); j++) {
const Messages::Person::PhoneNumber& phone_number = person.phones(j);
switch (phone_number.type()) {
case Messages::Person::MOBILE:
cout << " Mobile phone #: ";
break;
case Messages::Person::HOME:
cout << " Home phone #: ";
break;
case Messages::Person::WORK:
cout << " Work phone #: ";
break;
default:
cout << " Unknown phone #: ";
break;
}
cout << phone_number.number() << endl;
}
}
}