【问题标题】:C++ Builder XE2, receiving tcp requestsC++ Builder XE2,接收tcp请求
【发布时间】:2014-05-07 06:08:30
【问题描述】:

我想在我的应用程序中编写一个 tcp-listener,以便它可以被其他应用程序控制。

为此,我使用我找到的以下 sn-p(作为使用侦听器的示例)。

我曾经在 C#.NET 中使用过 p2p-connections 和 Sockets,但它不是很久以前就是太不同了。我希望代码在listen() 命令处停止并等到该端口有连接请求。然而,它只是继续下一行。通常我的防火墙也应该告诉我,如果有一些互联网活动尝试,但它保持沉默。

真正知道是否有连接请求的下一步是什么? 我可以使用浏览器通过对127.0.0.1:27015 的 HTTP 请求来触发它吗? 还是可以更轻松地存档?

#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;
}

【问题讨论】:

    标签: c++ sockets tcp c++builder


    【解决方案1】:

    我希望代码在 listen() 命令处停止并等到该端口有连接请求。

    没有。您正在考虑accept()listen() 只是打开端口,然后立即退出。然后,您必须在循环中使用accept() 来接受单个客户端连接。它返回一个新的SOCKET,您可以使用该SOCKET 与该特定客户端交换数据。您可以在调用accept() 之前使用select() 了解新客户端何时尝试连接,或者您可以让accept() 阻塞调用线程,直到客户端连接为止。

    您应该使用预先存在的 TCP 服务器组件,而不是编写自己的套接字 API 代码,例如 VCL 的原生 TServerSocket 组件或 Indy 的 TIdTCPServer 组件。

    【讨论】:

    • 感谢您的信息!我想改用TServerSocket,但是,即使根据docwiki.embarcadero.com/RADStudio/XE3/en/… 添加组件,该组件也不会出现在我的工具中。另外,当我尝试使用TServerSocket Jsocket; 时,它会显示"undefined Symbol TServerSocket"。我有#include &lt;vcl.h&gt;...还需要什么吗?
    • 安装 dclsockets 包对我来说很好。至于错误,TServerSocket 是在System.Win.ScktComp.hpp 中声明的。作为TObject 的后代,您必须在运行时动态实例化它:TServerSocket *Jsocket = new TServerSocket(DesiredOwner);
    • 没什么,如果你使用TIdTCPServer,它只支持阻塞模式......如果你的项目需要非阻塞套接字,不要浪费时间学习它:) TServerSocket 应该可以正常工作,IDK 为什么他们让你跳过箍来使用它。
    • 我猜#include &lt;ScktComp.hpp&gt; 不见了。但是,如果我尝试使用TServerSocket *Sock = new TServerSocket(NULL); 创建一个新的 TServerSocket,我会收到一个链接错误unresolved external 'System::Win::Scktcomp::TServerSocket::' 。我正在使用控制台应用程序。这可能是问题吗?
    • @MattMcNabb: TClientSocketTServerSocket 已被弃用,这就是它们不再默认安装的原因。
    猜你喜欢
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 2012-04-17
    相关资源
    最近更新 更多