include cstdio include cstdlib include unistd include sys types includ

  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
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
typedef struct ServerInfo {
int sock;
struct sockaddr_in addr;
} _ServerInfo;
enum {
E_OK = 0,
E_SOCKET_OPEN,
E_BIND,
E_LISTEN,
};
class Server {
int sock;
struct sockaddr_in addr;
unsigned long bind_ip;
unsigned short bind_port;
typedef void (*onRequest)(Server *, unsigned int, int client);
typedef struct ThreadProxyArgs {
Server *self;
int sock;
unsigned int thread_id;
onRequest function;
} ThreadProxyArgs;
bool stop_server;
public:
Server() {
}
void setup(unsigned long bind_ip, unsigned short port) {
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(bind_ip);
}
bool run(onRequest function, unsigned int max_threads, int backlog, int errors) {
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Can't open socket!");
return false;
}
int flag = true;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) != 0) {
perror("Can't set socket option!");
return false;
}
if (bind(sock, (struct sockaddr *)&(addr), sizeof(addr)) != 0) {
perror("Can't bind socket!");
return false;
}
if (listen(sock, 1) != 0) {
perror("Can't listen socket!");
return false;
}
pthread_t *threads = new pthread_t[max_threads];
unsigned int threads_cnt = 0;
int client;
bool force_errors = (errors == -1);
ThreadProxyArgs *proxy_args;
while (force_errors || errors--) {
while ((client = accept(sock, NULL, NULL)) >= 0) {
proxy_args = (ThreadProxyArgs *) malloc(sizeof(ThreadProxyArgs));
proxy_args->self = this;
proxy_args->sock = client;
proxy_args->function = function;
proxy_args->thread_id = threads_cnt;
pthread_create(&threads[threads_cnt++], NULL, threadProxy, (void *) proxy_args);
if (threads_cnt >= max_threads) {
while (threads_cnt > 0)
pthread_join(threads[--threads_cnt], NULL);
}
}
if (threads_cnt > 0) {
while (threads_cnt > 0)
pthread_join(threads[--threads_cnt], NULL);
}
printf("errror: %s\n", strerror(errno));
break;
}
return true;
}
static void *threadProxy(void *f) {
ThreadProxyArgs *args = (ThreadProxyArgs *) f;
args->function(args->self, args->thread_id, args->sock);
shutdown(args->sock, SHUT_RDWR);
close(args->sock);
free(args);
return NULL;
}
~Server() {
if (sock > -1) {
shutdown(sock, SHUT_RDWR);
close(sock);
}
}
};
void test(Server *s, unsigned int thread_id, int client) {
// printf("thread_id = %d\n", thread_id);
// printf("client = %d\n", client);
// printf("==============\n");
// char buffer[1024 + 1];
// int readed;
// while ((readed = recv(client, &buffer, sizeof(buffer) - 1, 0)) >= 0) {
// buffer[readed] = 0;
// printf("%s", buffer);
// }
static const char html[] = "HTTP/1.1 404 Not Found\r\n\
Server: xujpizdajgurda_server_v1.0.0.alpha.beta_ZVER_REPACK_BY_VOVAN666_MOD_BY_DELLOS_CRACKED_BY_JWW87-SPACES.SRU.JPEG\r\n\
Content-Type: text/html\r\n\
Content-Length: 1000050000\r\n\
Connection: close\r\n\
\r\n\
<div>XUJ PIZD JGURDA SERVER</div>\n\
";
send(client, html, sizeof(html) - 1, MSG_WAITALL);
}
void sig_handler(int param) {
printf("sig_handler(%d)\n", param);
// printf(" SIGABRT = %d\n", SIGABRT);
// printf(" SIGFPE = %d\n", SIGFPE);
// printf(" SIGILL = %d\n", SIGILL);
// printf(" SIGSEGV = %d\n", SIGSEGV);
// printf(" SIGTERM = %d\n", SIGTERM);
exit(param);
}
int main() {
signal(SIGABRT, sig_handler);
signal(SIGFPE, sig_handler);
signal(SIGILL, sig_handler);
signal(SIGSEGV, sig_handler);
signal(SIGTERM, sig_handler);
Server s;
s.setup(INADDR_LOOPBACK, 1488);
s.run(test, 3, 300, -1);
return 0;
}