Created
September 26, 2021 19:35
-
-
Save motoroller95/93a0712244d870e8d8db0dcc1cdeacd4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <stdio.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include <sys/shm.h> | |
#include <thread> | |
#include <iostream> | |
#define PORT 2000 | |
#define QUEUE 1024 | |
#include <queue> | |
#include <mutex> | |
#include <condition_variable> | |
// A threadsafe-queue. | |
template <class T> | |
class SafeQueue | |
{ | |
public: | |
SafeQueue(void) | |
: q() | |
, m() | |
, c() | |
{} | |
~SafeQueue(void) | |
{} | |
// Add an element to the queue. | |
void enqueue(T t) | |
{ | |
std::lock_guard<std::mutex> lock(m); | |
q.push(t); | |
c.notify_one(); | |
} | |
// Get the "front"-element. | |
// If the queue is empty, wait till a element is avaiable. | |
T dequeue(void) | |
{ | |
std::unique_lock<std::mutex> lock(m); | |
while(q.empty()) | |
{ | |
// release lock as long as the wait and reaquire it afterwards. | |
c.wait(lock); | |
} | |
T val = q.front(); | |
q.pop(); | |
return val; | |
} | |
private: | |
std::queue<T> q; | |
mutable std::mutex m; | |
std::condition_variable c; | |
}; | |
void thread_task(int ss, SafeQueue<int> &connections) { | |
char buffer[1024]; | |
while (true) { | |
int conn = connections.dequeue(); | |
memset(buffer, 0 ,sizeof(buffer)); | |
recv(conn, buffer, sizeof(buffer), 0); | |
send(conn, "hello world\n", strlen("hello world\n") , 0); | |
if (close(conn) != 0) | |
std::cout << "error"; | |
} | |
} | |
int main() { | |
int ss = socket(AF_INET, SOCK_STREAM, 0); | |
struct sockaddr_in server_sockaddr; | |
server_sockaddr.sin_family = AF_INET; | |
server_sockaddr.sin_port = htons(PORT); | |
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); | |
if(bind(ss, (struct sockaddr* ) &server_sockaddr, sizeof(server_sockaddr))==-1) { | |
perror("bind"); | |
exit(1); | |
} | |
if(listen(ss, QUEUE) == -1) { | |
perror("listen"); | |
exit(1); | |
} | |
for (int i = 0; i < 1; i++) { | |
int pid = fork(); | |
if (pid < 0) { | |
std::cout << "error fork"; | |
return -1; | |
} | |
if (pid == 0) { | |
SafeQueue<int> connections; | |
for (int i = 0; i < 25; i++) | |
std::thread(thread_task, ss, std::ref(connections)).detach(); | |
struct sockaddr_in client_addr; | |
socklen_t length = sizeof(client_addr); | |
while (1) { | |
int conn = accept(ss, (struct sockaddr*)&client_addr, &length); | |
if( conn < 0 ) | |
continue; | |
connections.enqueue(conn); | |
} | |
} | |
} | |
while(1) { | |
sleep(10); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment