2012-04-29 41 views
-1

我需要幫助,在新線程中組織每個請求處理傳入連接(代碼位於本主題的底部)。如何爲新線程中的每個請求處理組織隊列?

我不知道如何手動組織(不使用boost/threadpool)隊列來處理每個請求?我應該如何解決不使用boost等這樣的問題?

原因,我希望做手工,我不明白怎麼做了下:

  • 監聽每個新的連接
  • 如果我有新的連接,然後在發送新的線程經辦
  • 當線頭處理過程中,關閉此線程

我試圖做這樣的東西,與而(真);,但不知道如何很好地組織好請求隊列來處理每個HTTP請求。

我的代碼是:

#include <iostream> 
#include <Windows.h> 

#pragma comment(lib, "Ws2_32.lib") 

typedef struct Header 
{ 
friend struct Net; 

private: 
    WORD wsa_version; 
    WSAData wsa_data; 

    SOCKET sock; 
    SOCKADDR_IN service; 

    char *ip; 
    unsigned short port; 

public: 
    Header(void) 
    { 
     wsa_version = 0x202; 

     ip = "0x7f.0.0.1"; 
     port = 0x51; 

     service.sin_family = AF_INET; 
     service.sin_addr.s_addr = inet_addr(ip); 
     service.sin_port = htons(port); 
    } 

} Header; 

typedef struct Net 
{ 
private: 
    int result; 

    HANDLE thrd; 
    DWORD exit_code; 

    void WSAInit(WSAData *data, WORD *wsa_version) 
    { 
     result = WSAStartup(*wsa_version, &(*data)); 

     if(result != NO_ERROR) 
     { 
      std::cout << "WSAStartup() failed with the error: " << result << std::endl; 
     } 
     else 
     { 
      std::cout << (*data).szDescription << " " << (*data).szSystemStatus << std::endl; 
     } 
    } 

    void SocketInit(SOCKET *my_socket) 
    { 
     (*my_socket) = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

     if((*my_socket) == INVALID_SOCKET) 
     { 
      std::cout << "Socket initialization failed with the error: " << WSAGetLastError() << std::endl; 
      WSACleanup(); 
     } 
     else 
     { 
      std::cout << "Socket initialization successful!" << std::endl; 
     } 
    } 

    void SocketBind(SOCKET *my_socket, SOCKADDR_IN *service) 
    { 
     result = bind((*my_socket), (SOCKADDR*)&(*service), sizeof(*service)); 

     if(result == SOCKET_ERROR) 
     { 
      std::cout << "Socket binding failed with the error: " << WSAGetLastError() << std::endl; 
      closesocket((*my_socket)); 
      WSACleanup(); 
     } 
     else 
     { 
      std::cout << "Socket binding successful!" << std::endl; 
     } 

     result = listen(*my_socket, SOMAXCONN); 

     if(result == SOCKET_ERROR) 
     { 
      std::cout << "Socket listening failed with the error: " << WSAGetLastError() << std::endl; 
     } 
     else 
     { 
      std::cout << "Listening to the socket..." << std::endl; 
     } 
    } 

    void SocketAccept(SOCKET *my_socket) 
    { 
     SOCKET sock_accept = accept((*my_socket), 0, 0); 

     if(sock_accept == INVALID_SOCKET) 
     { 
      std::cout << "Accept failed with the error: " << WSAGetLastError() << std::endl; 
      closesocket(*my_socket); 
      WSACleanup(); 
     } 
     else 
     { 
      std::cout << "Client socket connected!" << std::endl; 

      thrd = CreateThread(NULL, 0, &Net::Threading, &sock_accept, 0, NULL); 
     } 
    } 

    static void HandleRequest(char response[], int length) 
    { 
     std::cout << std::endl; 

     for(int i = 0; i < length; i++) 
     { 
      std::cout << response[i]; 
     } 

     std::cout << std::endl; 
    } 

    static DWORD WINAPI Threading(LPVOID lpParam) 
    { 
     SOCKET *my_socket = (SOCKET*)lpParam; 

     char data[0x400]; 
     int result = recv((*my_socket), data, sizeof(data), 0); 
     HandleRequest(data, result); 
     char *response = "HTTP/1.1 200 OK\r\nServer: Amegas.sys-IS/1.0\r\nContent-type: text/html\r\nSet-Cookie: ASD643DUQE7423HFDG; path=/\r\nCache-control: private\r\n\r\n<h1>Hello World!</h1>\r\n\r\n"; 
     result = send((*my_socket), response, (int)strlen(response), 0); 

     if(result == SOCKET_ERROR) 
     { 
      std::cout << "Sending data via socket failed with the error: " << WSAGetLastError() << std::endl; 
      closesocket((*my_socket)); 
      WSACleanup(); 
     } 
     else 
     { 
      result = shutdown((*my_socket), 2); 
     } 

     return 0; 
    } 

public: 
    Net(void) 
    { 
     Header *obj_h = new Header(); 

     WSAInit(&obj_h->wsa_data, &obj_h->wsa_version); 

     SocketInit(&obj_h->sock); 
     SocketBind(&obj_h->sock, &obj_h->service); 

     SocketAccept(&obj_h->sock); 

     delete obj_h; 
    } 
} Net; 

int main(void) 
{ 
    Net *obj_net = new Net(); 

    delete obj_net; 

    return 0; 
} 

回答

2

您的操作系統將負責接受()排隊 - 不要擔心太多。簡單的同步服務器往往可以這樣運行:

socket listeningSocket:=socket.create; 
listeningSocket.bind('0.0.0.0',80); // address/port 
listeningSocket.listen; 

while(true){ 
    socket serverClientSocket=accept(listeningSocket); 
    createThread(&serverClientThread,serverClientSocket); 
} 

void serverClientThread(void *param) 
{ 
    inBuffer char[256]; 
    socket myServerClientSocket=(socket)param; 
    while(true){ 
    int bytesRx=recv(myServerClientSocket,&inBuffer,size(inBuffer)); 
    if (bytesRx>0){ 
     if doSomethingWith(&inBuffer,bytesRx) // not necessarily size(inBuffer) bytes!! 
     { 
      send(myServerClientSocket,"Reply from server\r\n"); 
     } 

    } 
    else 
     return; // on error or connection closed 
    } 
} 

的一個監聽線程,(可以在控制檯應用程序的主線程),運行在接受()循環foerver。單獨的serverClientThread實例將運行,直到它們的客戶端出現故障或出現其他錯誤。

+0

有人認爲這是事實上不準確或誤導? –

+0

+1這是一個艱難的馬丁。你能否介入一位主持人?也許發佈元? – Gray

相關問題