-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic_server.cpp
More file actions
151 lines (128 loc) · 3.69 KB
/
basic_server.cpp
File metadata and controls
151 lines (128 loc) · 3.69 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
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <unistd.h>
#include <vector>
#include <iostream>
#include <thread>
#include <sys/epoll.h>
#include <arpa/inet.h>
#include "data.h"
#include "worker.h"
#define LENGTH_OF_SERVER_LISTEN_QUEUE 10000
#define NUM_WORKERS 20
static std::vector<SingleThreadWorker> works(NUM_WORKERS);
void Process(int);
void Work(int i) {
while (true) {
int socket = works[i].getConnection();
if (socket == -1) {
continue;
} else {
Process(socket);
}
}
}
void Process(int client_socket) {
// receive the Package from the client
char recvPackage[PACKAGE_BUFFER_SIZE];
Package buffer;
memset(&buffer, 0, sizeof(Package)); // clean to 0
ssize_t rs = recv(client_socket, recvPackage, PACKAGE_BUFFER_SIZE, 0);
memcpy(&buffer, recvPackage, sizeof(Package));
#ifdef DEBUG_OUTPUT
printf("recv over id:%u, key:%d, value:%d\n", (unsigned int) buffer.id, buffer.key.id, buffer.value.id);
#endif
// send the response
int sendbytes;
Result result(buffer.id);
if ((sendbytes = send(client_socket, (char *) &result, sizeof(Result), 0)) == -1) {
perror("respond");
exit(1);
}
#ifdef DEBUG_OUTPUT
printf("send the Result, id:%d\n", result.id);
#endif
close(client_socket);
}
void InitializeWorkers(std::vector<std::thread> &workers) {
for (int i = 0; i < NUM_WORKERS; ++i) {
workers.push_back(std::thread(Work, i));
if (workers[i].joinable()) {
workers[i].detach();
}
}
}
void polling(std::vector<std::thread> &workers, int64_t count, int connection) {
works[count % NUM_WORKERS].addConnections(connection);
}
int main(int argc, char **argv) {
// set socket's address information
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
int server_port = SERVER_PORT;
if (argc > 1) {
server_port = atoi(argv[1]);
}
server_addr.sin_port = htons(server_port);
// create a stream socket
int server_fd = socket(PF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
printf("Create Socket Failed!\n");
exit(1);
}
//bind
if (bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr))) {
printf("Server Bind Port: %d Failed!\n", server_port);
exit(1);
}
// listen
if (listen(server_fd, LENGTH_OF_SERVER_LISTEN_QUEUE)) {
printf("Server Listen Failed!\n");
exit(1);
}
// initializeWorkers
std::vector<std::thread> workers(NUM_WORKERS);
InitializeWorkers(workers);
int64_t count = 0;
while (true) {
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
int new_client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &length);
if (new_client_fd < 0) {
printf("Server Accept Failed!\n");
break;
}
// multithreading version
// distribute each FD's activity to one of the thread
polling(workers, count, new_client_fd);
count++;
// if uncomment the following part,
// the server will do single thread send and receive
/*
// receive the Package from the client
char recvPackage[PACKAGE_BUFFER_SIZE];
Package buffer;
memset(&buffer, 0, sizeof(Package)); // clean to 0
ssize_t rs = recv(new_client_fd, recvPackage, PACKAGE_BUFFER_SIZE, 0);
memcpy(&buffer, recvPackage, sizeof(Package));
printf("recv over id:%u, key:%d, value:%d\n", (unsigned int) buffer.id, buffer.key.id, buffer.value.id);
// send the response
int sendbytes;
Result result(buffer.id);
if ((sendbytes = send(new_client_fd, (char *) &result, sizeof(Result), 0)) == -1) {
perror("respond");
exit(1);
}
printf("send the Result, id:%d\n",result.id);
close(new_client_fd);
*/
}
close(server_fd);
return 0;
}