Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define WIN32_LEAN_AND_MEAN
- #include <Windows.h>
- #include <WinSock2.h>
- #include <WS2tcpip.h>
- #include <stdlib.h>
- #include <iostream>
- #include <string>
- #include <thread>
- #include <map>
- #include <vector>
- #define SERVER_PORT "20516"
- #define DEFAULT_BUFLEN 512
- #pragma comment(lib, "Ws2_32.lib")
- std::thread _socket_accept_thread;
- std::vector<std::thread> _client_threads;
- std::vector<SOCKET> _clients;
- std::map <SOCKET, std::string > _client_idents;
- SOCKET listen_socket = INVALID_SOCKET, client_socket = INVALID_SOCKET;
- struct addrinfo *results = NULL, hints;
- bool _stopping = FALSE;
- void socket_accept_loop();
- void process_socket_loop(SOCKET&);
- void process_line(std::string);
- std::vector<std::string> split_args(std::string);
- std::string recv_line(SOCKET&);
- void cleanup();
- enum chat_commands{
- chat_users,
- chat_send,
- chat_online,
- chat_none,
- };
- std::map<chat_commands, std::string> chat_command_map = {
- { chat_users, "USR" },
- { chat_send, "SEND" },
- { chat_online, "ONL" },
- };
- int main(int argc, char ** argv){
- WSAData wsa_data;
- int result;
- result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
- if (result){
- std::cout << "WSAStartup error: " << result << std::endl;
- return 1;
- }
- ZeroMemory(&hints, sizeof(hints));
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE;
- result = getaddrinfo(NULL, SERVER_PORT, &hints, &results);
- if (result){
- std::cout << "getaddrinfo failed: " << result << std::endl;
- WSACleanup();
- return 1;
- }
- listen_socket = socket(results->ai_family, results->ai_socktype, results->ai_protocol);
- if (listen_socket == INVALID_SOCKET){
- std::cout << "Failed to create listen_socket: " << WSAGetLastError() << std::endl;
- return 1;
- }
- result = bind(listen_socket, results->ai_addr, (int)results->ai_addrlen);
- if (result == SOCKET_ERROR){
- std::cout << "Failed to bind to SERVER_PORT. " << WSAGetLastError() << std::endl;
- freeaddrinfo(results);
- closesocket(listen_socket);
- WSACleanup();
- return 1;
- }
- freeaddrinfo(results);
- result = listen(listen_socket, SOMAXCONN);
- if (result == SOCKET_ERROR){
- std::cout << "Failed to begin listening on SERVER_PORT " << WSAGetLastError() << std::endl;
- closesocket(listen_socket);
- WSACleanup();
- return 1;
- }
- _socket_accept_thread = std::thread(socket_accept_loop);
- std::string in;
- do
- {
- std::getline(std::cin, in);
- }
- while (in.find("stop") == std::string::npos);
- cleanup();
- }
- void cleanup(){
- _stopping = true;
- closesocket(listen_socket);
- if (_clients.size() > 0){
- for (std::vector<SOCKET>::iterator it = _clients.begin(); it != _clients.end(); ++it){
- if ((*it) != INVALID_SOCKET);
- closesocket(*it);
- }
- }
- WSACleanup();
- _socket_accept_thread.join();
- for (std::vector<std::thread>::iterator it = _client_threads.begin(); it != _client_threads.end(); ++it){
- if ((*it).joinable())
- (*it).join();
- }
- }
- void socket_accept_loop(){
- do{
- struct sockaddr_in client_info = { 0 };
- int size = sizeof(client_info);
- char clientaddr[INET6_ADDRSTRLEN];
- client_socket = accept(listen_socket, (sockaddr*)&client_info, &size);
- if (client_socket != INVALID_SOCKET){
- inet_ntop(client_info.sin_family, &client_info.sin_addr, clientaddr, INET6_ADDRSTRLEN);
- std::cout << "Accepted: " << clientaddr << std::endl;
- _clients.push_back(client_socket);
- _client_threads.push_back(std::thread(process_socket_loop, client_socket));
- }
- } while (!_stopping);
- }
- std::string recv_line(SOCKET & s){
- std::string recv_str;
- int recvlen;
- do{
- char recv_buffer[DEFAULT_BUFLEN];
- recvlen = recv(s, recv_buffer, DEFAULT_BUFLEN, 0);
- if (recvlen > 0)
- recv_str.append(recv_buffer, 0, recvlen);
- } while (recv_str.find('\n') == std::string::npos && recvlen > 0);
- return recv_str;
- }
- void process_socket_loop(SOCKET & s){
- std::string recv_str;
- do{
- recv_str = recv_line(s);
- process_line(recv_str);
- } while (!_stopping);
- }
- std::vector<std::string> split_args(std::string _s){
- std::vector<std::string> split_strings;
- std::string s(_s);
- int pos;
- while ((pos = s.find(' ')) != std::string::npos){
- split_strings.push_back(s.substr(0, pos));
- s.erase(0, pos + 1);
- }
- split_strings.push_back(s); //pushes what's left of the string to the vector
- return split_strings;
- }
- void process_line(std::string _s){
- chat_commands cur_command = chat_none;
- std::vector<std::string> args;
- for (std::map<chat_commands, std::string>::iterator it = chat_command_map.begin(); it != chat_command_map.end(); ++it){
- if (_s.find((*it).second) != std::string::npos){
- cur_command = (*it).first;
- }
- }
- if (cur_command == chat_none){
- return;
- }
- else{
- _s.erase(0, chat_command_map[cur_command].size() + 1);
- args = split_args(_s);
- std::cout << "COMMAND: " << chat_command_map[cur_command].c_str() << std::endl << "ARGS: " << _s.c_str() << std::endl;
- }
- switch (cur_command){
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement