I make an HTTP server, or rather a class so that there will always be a high-level tool for this task. But it blocks the program's robot waiting for a request. How to make it so that it does not block the progress of the execution.

#include <iostream> #include <sstream> #include <string> #include <fstream> #include <stdlib.h> #define _WIN32_WINNT 0x501 #include <WinSock2.h> #include <WS2tcpip.h> // НСобходимо, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠ° происходила с DLL-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ // Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сокСтам #pragma comment(lib, "Ws2_32.lib") using std::cerr; const int max_client_buffer_size = 1024; char buf[max_client_buffer_size]; int client_socket = INVALID_SOCKET; class HTTPserver { public: bool error; WSADATA wsaData; // слуТСбная структура для Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ // ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Windows Sockets // старт использования Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ сокСтов процСссом // (подгруТаСтся Ws2_32.dll) int result;// = WSAStartup(MAKEWORD(2, 2), &wsaData); struct addrinfo* addr;// = NULL; // структура, хранящая ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ // ΠΎΠ± IP-адрСсС ΡΠ»ΡƒΡ‰Π°ΡŽΡ‰Π΅Π³ΠΎ сокСта // Π¨Π°Π±Π»ΠΎΠ½ для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ структуры адрСса struct addrinfo hints; int listen_socket; HTTPserver(char* ip,char *port) { error = false; result = WSAStartup(MAKEWORD(2, 2), &wsaData); // Если ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка ΠΏΠΎΠ΄Π³Ρ€ΡƒΠ·ΠΊΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ if (result != 0) { cerr << "WSAStartup failed: " << result << "\n"; //return result; error = true; return; } addr = NULL; // структура, хранящая ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ // Π¨Π°Π±Π»ΠΎΠ½ для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ структуры адрСса //struct addrinfo hints; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; // AF_INET опрСдСляСт, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΡΠ΅Ρ‚ΡŒ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сокСтом hints.ai_socktype = SOCK_STREAM; // Π—Π°Π΄Π°Π΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΉ Ρ‚ΠΈΠΏ сокСта hints.ai_protocol = IPPROTO_TCP; // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» TCP hints.ai_flags = AI_PASSIVE; // Π‘ΠΎΠΊΠ΅Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ Π±ΠΈΠ½Π΄ΠΈΡ‚ΡŒΡΡ Π½Π° адрСс, // Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ входящиС соСдинСния // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ структуру, Ρ…Ρ€Π°Π½ΡΡ‰ΡƒΡŽ адрСс сокСта - addr // Наш HTTP-сСрвСр Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΈΡΠ΅Ρ‚ΡŒ Π½Π° 8000-ΠΌ ΠΏΠΎΡ€Ρ‚Ρƒ локалхоста result = getaddrinfo(ip, port, &hints, &addr); // Если инициализация структуры адрСса Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»Π°ΡΡŒ с ошибкой, // Π²Ρ‹Π²Π΅Π΄Π΅ΠΌ сообщСниСм ΠΎΠ± этом ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ if (result != 0) { cerr << "getaddrinfo failed: " << result << "\n"; WSACleanup(); // Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Ws2_32.dll //return 1; error = false; return; } // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сокСта listen_socket = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); // Если созданиС сокСта Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΠΎΡΡŒ с ошибкой, Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ сообщСниС, // освобоТдаСм ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ΄ структуру addr, // Π²Ρ‹Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ dll-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ ΠΈ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ if (listen_socket == INVALID_SOCKET) { cerr << "Error at socket: " << WSAGetLastError() << "\n"; freeaddrinfo(addr); WSACleanup(); //return 1; error = false; return; } // ΠŸΡ€ΠΈΠ²ΡΠ·Ρ‹Π²Π°Π΅ΠΌ сокСт ΠΊ IP-адрСсу result = bind(listen_socket, addr->ai_addr, (int)addr->ai_addrlen); // Если ΠΏΡ€ΠΈΠ²ΡΠ·Π°Ρ‚ΡŒ адрСс ΠΊ сокСту Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ, Ρ‚ΠΎ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ сообщСниС // ΠΎΠ± ошибкС, освобоТдаСм ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ΄ структуру addr. // ΠΈ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ сокСт. // Π’Ρ‹Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ DLL-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ ΠΈΠ· памяти ΠΈ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. if (result == SOCKET_ERROR) { cerr << "bind failed with error: " << WSAGetLastError() << "\n"; freeaddrinfo(addr); closesocket(listen_socket); WSACleanup(); //return 1; error = false; return; } // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΡΠ»ΡƒΡˆΠ°ΡŽΡ‰ΠΈΠΉ сокСт if (listen(listen_socket, SOMAXCONN) == SOCKET_ERROR) { cerr << "listen failed with error: " << WSAGetLastError() << "\n"; closesocket(listen_socket); WSACleanup(); // return 1; error = false; return; } //const int max_client_buffer_size = 1024; //char buf[max_client_buffer_size]; client_socket = INVALID_SOCKET; } /*void Scan(std::string (*func)(std::string)) { std::string r = ""; Scan(func, r); }*/ void VerifyR(std::string (*func)(std::string)) { // for (;;) { // ΠŸΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ входящиС соСдинСния client_socket = accept(listen_socket, NULL, NULL); if (client_socket == INVALID_SOCKET) { cerr << "accept failed: " << WSAGetLastError() << "\n"; closesocket(listen_socket); WSACleanup(); // return 1; error = false; return; } result = recv(client_socket, buf, max_client_buffer_size, 0); std::stringstream response; // сюда Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒΡΡ ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ std::stringstream response_body; // Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° if (result == SOCKET_ERROR) { // ошибка получСния Π΄Π°Π½Π½Ρ‹Ρ… cerr << "recv failed: " << result << "\n"; closesocket(client_socket); } else if (result == 0) { // соСдинСниС Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ cerr << "connection closed...\n"; } else if (result > 0) { // ΠœΡ‹ Π·Π½Π°Π΅ΠΌ фактичСский Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, поэтому ставим ΠΌΠ΅Ρ‚ΠΊΡƒ ΠΊΠΎΠ½Ρ†Π° строки // Π’ Π±ΡƒΡ„Π΅Ρ€Π΅ запроса. buf[result] = '\0'; // Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ вСсь ΠΎΡ‚Π²Π΅Ρ‚ вмСстС с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°ΠΌΠΈ response << func(buf); // ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ send result = send(client_socket, response.str().c_str(), response.str().length(), 0); if (result == SOCKET_ERROR) { // ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅ Π΄Π°Π½Π½Ρ‹Ρ… cerr << "send failed: " << WSAGetLastError() << "\n"; } // Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ соСдинСниС ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ closesocket(client_socket); } } } void Verify(std::string (*func)(std::string)) { // ΠŸΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ входящиС соСдинСния client_socket = accept(listen_socket, NULL, NULL); if (client_socket == INVALID_SOCKET) {cerr << "accept failed: " << WSAGetLastError() << "\n"; closesocket(listen_socket); WSACleanup(); error = false; return; } result = recv(client_socket, buf, max_client_buffer_size, 0); std::stringstream response; // сюда Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒΡΡ ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ std::stringstream response_body; // Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° if (result == SOCKET_ERROR) { cerr << "recv failed: " << result << "\n"; closesocket(client_socket);} else if (result == 0) { cerr << "connection closed...\n";} else if (result > 0) { // ΠœΡ‹ Π·Π½Π°Π΅ΠΌ фактичСский Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, поэтому ставим ΠΌΠ΅Ρ‚ΠΊΡƒ ΠΊΠΎΠ½Ρ†Π° строки // Π’ Π±ΡƒΡ„Π΅Ρ€Π΅ запроса. buf[result] = '\0'; // Π”Π°Π½Π½Ρ‹Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ // Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° (HTML) response_body << func(buf); //ByString // Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ вСсь ΠΎΡ‚Π²Π΅Ρ‚ вмСстС с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°ΠΌΠΈ response << "HTTP/1.1 200 OK\r\n" << "Version: HTTP/1.1\r\n" << "Content-Type: text/html; charset=utf-8\r\n" << "Content-Length: " << response_body.str().length() << "\r\n\r\n" << response_body.str(); // ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ send result = send(client_socket, response.str().c_str(), response.str().length(), 0); if (result == SOCKET_ERROR) { // ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅ Π΄Π°Π½Π½Ρ‹Ρ… cerr << "send failed: " << WSAGetLastError() << "\n"; } // Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ соСдинСниС ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ closesocket(client_socket); } } ~HTTPserver() { // Π£Π±ΠΈΡ€Π°Π΅ΠΌ Π·Π° собой closesocket(listen_socket); freeaddrinfo(addr); WSACleanup(); } }; //ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π†Π  ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠΎΠΏΠ°Π²ΡˆΡ‹ΠΉΡΡ std::string GetIP() { std::string out = "WinSock ERR"; WSADATA wsaData; if (!WSAStartup(WINSOCK_VERSION, &wsaData)){char chInfo[64]; if (!gethostname(chInfo, sizeof(chInfo))) { hostent *sh; sh=gethostbyname((char*)&chInfo); if (sh!=NULL) { int nAdapter = 0; while (sh->h_addr_list[nAdapter]) { struct sockaddr_in adr; memcpy(&adr.sin_addr, sh->h_addr_list[nAdapter], sh->h_length); out = inet_ntoa(adr.sin_addr); nAdapter++; } } } } WSACleanup(); return out; } //ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ„Π°ΠΈΠ» Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ строки bool getFile(char* url,std::string &r) { r = ""; std::ifstream in(url); if(in) { while(1) { char t; in.get(t); if(in.eof()) break; r+=t; } in.close(); } else return false; return true; } std::string reqset(std::string zapross) { std::string zp; std::ifstream in("index.html"); if(in) { while(1) { char t = in.get(); if(in.eof()) break; zp+=t; } in.close(); } else zp = "Noo File"; zp+="<p>Zapross send v otvet</p>"; zapross; for(int i = 0; i < zapross.size(); i++) { if(zapross[i] != '\n') zp+= zapross[i]; else { zp+= "<p></p>"; } } return zp; } int main() { //ΠŸΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Ρ€Π΅Π°Π»ΡŒΠ½ΡƒΡŽ ip ΠΈΠ· Π°Π΄Π°ΠΏΡ‚ΠΎΡ€Π° ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ std::string sIP = GetIP(); std::cout<<sIP<<'\n'; //Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ip сСрвСра HTTPserver F((char*)sIP.c_str(),"80"); //Если ΠΎΡˆΡ‹Π±ΠΊΠΈ всё ΠΊΠΎΠ½Π΅Ρ† if(F.error) return 0; while(1) { //Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π½Π° ΠΎΠΆΡ‹Π΄Π°Π½ΠΈΠ΅ запросса F.Verify(reqset); std::cout<<"------\n"; } return 0; } 
  • Look towards the select () function and its analogues. Here's some example for winsock found winsocketdotnetworkprogramming.com/winsock2programming ... - Mike 4:02 pm
  • Notice that the socket on which listens are made is also translated into non-blocking mode and also fed to select among others - Mike at 4:06 pm
  • 1. socket NON BLOCK 2. Use Thread - NewView pm
  • Already tried to send a request to the stream, but something did not work. I'll try again. - Yuriy Pysanka

0