2014-05-01 99 views
0

我想在我的應用程序中編寫一個tcp-listener,因此它可以由其他應用程序控制。C++ Builder XE2,接收tcp請求

爲此,我使用了下面的代碼片段(作爲使用監聽器的示例)。

我曾經與p2p連接和套接字一起在C#.NET中工作過,但它要麼太早,要麼太不同了。我希望代碼在listen()命令處停止,並等到該端口發出連接請求。但是,它只是繼續下一行。通常我的防火牆也應該告訴我,如果有一些互聯網活動的嘗試,但它保持沉默。

實際知道是否存在連接請求的下一步是什麼? 我可以使用瀏覽器通過HTTP請求觸發127.0.0.1:27015嗎? 或者這可以歸檔更容易嗎?

#include <winsock.h> 
#pragma comment(lib, "Ws2_32.lib") 

int portlisten(){ 
    WSADATA wsaData; 
    int iResult = 0; 

    SOCKET ListenSocket = INVALID_SOCKET; 
    sockaddr_in service; 

    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 
    if (iResult != NO_ERROR) { 
     wprintf(L"WSAStartup() failed with error: %d\n", iResult); 
     return 1; 
    } 
    //---------------------- 
    // Create a SOCKET for listening for incoming connection requests. 
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (ListenSocket == INVALID_SOCKET) { 
     wprintf(L"socket function failed with error: %ld\n", WSAGetLastError()); 
     WSACleanup(); 
     return 1; 
    } 
    //---------------------- 
    // The sockaddr_in structure specifies the address family, 
    // IP address, and port for the socket that is being bound. 
    service.sin_family = AF_INET; 
    service.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    service.sin_port = htons(27015); 

    iResult = bind(ListenSocket, (SOCKADDR *) & service, sizeof (service)); 
    if (iResult == SOCKET_ERROR) { 
     wprintf(L"bind function failed with error %d\n", WSAGetLastError()); 
     iResult = closesocket(ListenSocket); 
     if (iResult == SOCKET_ERROR) 
      wprintf(L"closesocket function failed with error %d\n", WSAGetLastError()); 
     WSACleanup(); 
     return 1; 
    } 
    //---------------------- 
    // Listen for incoming connection requests 
    // on the created socket 
    if (listen(ListenSocket, 5) == SOCKET_ERROR) 
     wprintf(L"listen function failed with error: %d\n", WSAGetLastError()); 

    wprintf(L"Listening on socket...\n"); 

    iResult = closesocket(ListenSocket); 
    if (iResult == SOCKET_ERROR) { 
     wprintf(L"closesocket function failed with error %d\n", WSAGetLastError()); 
     WSACleanup(); 
     return 1; 
    } 

    WSACleanup(); 
    return 0; 
} 

回答

2

我期望的代碼停在聽()命令,並等待,直到有在該端口的連接請求。

不,您正在考慮改爲accept()listen()只是打開端口,然後立即退出。您必須在循環中使用accept()來接受單個客戶端連接。它會返回一個新的SOCKET,用於與該特定客戶端交換數據。在調用accept()之前,您可以使用select()來知道新客戶端何時嘗試連接,或者您可以讓accept()阻止調用線程,直到客戶端連接。

不應編寫自己的套接字API代碼,而應使用預先存在的TCP服務器組件,如VCL的本地TServerSocket組件或Indy的TIdTCPServer組件。

+0

感謝您的信息!我想使用'TServerSocket'來代替,但是,即使按照http://docwiki.embarcadero.com/RADStudio/XE3/en/Installing_Socket_Components添加了komponent,組件也不會出現在我的工具中。另外,當我嘗試使用'TServerSocket Jsocket;'它說''未定義的符號TServerSocket「'。我有'#include '......其他需要的東西? – Julian

+0

安裝'dclsockets'包對我來說工作正常。至於錯誤,'TServerSocket'在'System.Win.ScktComp.hpp'中聲明。作爲'TObject'後代,你必須在運行時動態地實例化它:'TServerSocket * Jsocket = new TServerSocket(DesiredOwner);' –

+0

只要你使用'TIdTCPServer',它就只支持阻塞模式......不要浪費時間學習它,如果你的項目需要非阻塞套接字:) TServerSocket應該可以正常工作,IDK爲什麼會讓你跳過使用它。 –