C ++套接字(TCP)不接受Windows上的外部连接,但在Linux上

时间:2018-01-02 08:39:04

标签: c++ linux windows sockets tcp

我正在研究一个简单的网络服务器示例。它应接受TCP和UDP请求并使用asctime字符串进行应答。 UDP正在解决任何问题。 TCP在Windows上出现了一些问题。我自己在linux上工作,但必须在Windows上运行这个小例子。大学的PC正在运行Windows。因此,为了您的信息,我尝试了交叉编译甚至编译系统本身。

Linux上的实际问题是一切正常。以下代码是我尝试实现非阻塞TCP侦听器,它在获取请求时用asctime-string响应(用户定义的端口不仅仅是13):

void Server::tcpListen(int port)
{
    socklen_t size = sizeof(sockaddr);
    sockaddr_in remoteHost;

    mAddress.sin_port = htons(port);

    int r = bind(mTcpSocket, (sockaddr*) &mAddress, sizeof(sockaddr));

    if(r < 0)
    {
        cerr << "Couldn't bind port. (" << std::strerror(errno) << " " << errno << ")" << endl;
        #ifdef WIN32
                cerr << "WSA Error: " << WSAGetLastError() << endl;
        #endif
        mTcpServerRunning = false;
        return;
    }

    cout << "TCP:\tListen on port " << port << '\n';

    r = listen(mTcpSocket, 5);

    if(r < 0)
    {
        cerr << "Couldn't listen. " << std::strerror(errno) << " " << endl;
        mTcpServerRunning = false;
        return;
    }

    time_t t;
    struct tm *timeinfo;
    std::string timeMsg;

    mTcpServerRunning = true;

    while(mTcpServerRunning)
    {
        int cSock = accept(mTcpSocket, (sockaddr*) &remoteHost, &size);
        if(cSock < 0)
        {
            continue;
        }

        char buf[5];

        r = recv(cSock, buf, sizeof(buf), 0);

        if(r > 0)
        {
            time(&t);
            timeinfo = localtime(&t);
            timeMsg = asctime(timeinfo);

            r = send(cSock, (char*) timeMsg.c_str(), timeMsg.length(), 0);

            if(r < 0)
            {
                cerr << "send error: " << errno << endl;
                exit(EXIT_FAILURE);
            }

            uint8_t ip[4];
            memcpy(ip, &remoteHost.sin_addr.s_addr, sizeof(ip));

            cout << "-----------------------------------------------------" << endl;
            cout << "Request-Type: TCP" << " / " << timeMsg.c_str() << endl;
            cout << "IP: "
                    << (int) ip[0]
                    << "." << (int) ip[1]
                    << "." << (int) ip[2]
                    << "." << (int) ip[3]
                    << " / Port (Client): " << remoteHost.sin_port << endl;
            cout << "-----------------------------------------------------" << endl;   
        }
    }
    close(mTcpSocket);
    #ifdef WIN32
        WSACleanup();
    #endif
    mTcpServerRunning = false;
}

为了调试连接,我使用了wireshark,告诉我连接尝试没有得到答复。通过三次握手的初始化工作(SYN-> SYN,ACK-> ACK)。甚至请求(空字符串)也正常工作。 (PSH,ACK - > ACK)但服务器不响应时间字符串。我打开了端口,甚至完全禁用了防火墙。

WSASocket使用有什么问题吗?阻止TCP接收也不起作用。在回答之前我已经考虑了循环重复,然后覆盖了从accept返回的cSock描述符。

编辑:套接字初始化:

#ifdef WIN32
    WSADATA wsaData;
    if (WSAStartup (MAKEWORD(1, 1), &wsaData) != 0) {
        fprintf (stderr, "WSAStartup(): Couldn't initialize Winsock.\n");
        exit (EXIT_FAILURE);
    }
#endif

mTcpSocket = socket(AF_INET, SOCK_STREAM, 0);
mUdpSocket = socket(AF_INET, SOCK_DGRAM, 0);

#ifdef _WIN32
    unsigned long nonblocking = 1;

//            if(ioctlsocket(mTcpSocket,FIONBIO, &nonblocking))
//                    std::cout << "Couldn't set TCP-Socket to nonblocking mode! ("
//                                    << std::strerror(errno) << ")" << endl;

    if(ioctlsocket(mUdpSocket, FIONBIO, &nonblocking))
            std::cerr << "Couldn't set UDP-Socket to nonblocking mode! ("
                            << std::strerror(errno) << ")" << endl;
#else

    int tcpFlags = fcntl(mTcpSocket, F_GETFL, 0);
    int udpFlags = fcntl(mUdpSocket, F_GETFL, 0);

    if(fcntl(mTcpSocket, F_SETFL, tcpFlags | O_NONBLOCK))
        std::cout << "Couldn't set TCP-Socket to nonblocking mode! ("
                << std::strerror(errno) << ")" << endl;

    if(fcntl(mUdpSocket, F_SETFL, udpFlags | O_NONBLOCK))
        std::cerr << "Couldn't set UDP-Socket to nonblocking mode! ("
                << std::strerror(errno) << ")" << endl;
#endif

0 个答案:

没有答案