WinSock服务器能够获取传入数据但无法连接到客户端

时间:2014-05-24 04:14:50

标签: c++ winsock

我正在研究一个简单的服务器程序,它使用127.0.0.1完美运行但是当我将IP设置为运行客户端的客户端(100.2.132.128)时,服务器只能接收并且无法发送。该代码主要基于MSDN。我使用Wire shark捕获Wire Shark之间的流量。 尝试将数据发送到客户端的服务器的源代码:

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

#define OUT_DEFAULT_BUFLEN 512
#define OUT_DEFAULT_PORT "20000"

bool Send(std::string arg, std::string IP){

if (arg.size() > 250){
    return false;
}

WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL, *ptr = NULL, hints;

int iResult;

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
    printf("WSAStartup failed with error: %d\n", iResult);
    return 1;
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

// Resolve the server address and port
iResult = getaddrinfo(IP.c_str(), OUT_DEFAULT_PORT, &hints, &result);

if (iResult != 0) {
    printf("getaddrinfo failed with error: %d\n", iResult);
    WSACleanup();
    return 1;
}

// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

    // Create a SOCKET for connecting to server 
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Connect to server.
    iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
        continue;
    }
    break;
}

freeaddrinfo(result);

if (ConnectSocket == INVALID_SOCKET) {
    printf("Unable to connect to server!\n");
    return 1;
}

char *cstr = InAppendSizePacket(arg);

iResult = send(ConnectSocket, cstr, (int)strlen(cstr), 0);
if (iResult == SOCKET_ERROR) {
    printf("send failed with error: %d\n", WSAGetLastError());
    closesocket(ConnectSocket);
    WSACleanup();
    return 1;
}

printf("Bytes Sent: %ld\n", iResult);

char recvbuf[OUT_DEFAULT_BUFLEN];
int recvbuflen = OUT_DEFAULT_BUFLEN;

// Receive until the peer closes the connection
do {
    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);

    if (iResult > 0){
        printf("Bytes received: %d\n", iResult);
        if (recvbuf[0] == 'O' && recvbuf[1] == 'K'){
            break;
        }
    }
    else if (iResult == 0){
        printf("Connection closed\n");
        int debug = 0;
    }
    else{
        printf("recv failed with error: %d\n", WSAGetLastError());
        int debug = 0;
    }
} while (iResult > 0);

std::cout << "The result is:" << recvbuf << std::endl;

iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
    printf("shutdown failed with error: %d\n", WSAGetLastError());
    closesocket(ConnectSocket);
    WSACleanup();
    return 1;
}

// cleanup
closesocket(ConnectSocket);
WSACleanup();

return 0;
}

等待从服务器接受数据的客户端的源代码是:

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

#define IN_DEFAULT_BUFLEN 512
#define IN_DEFAULT_PORT "20000"

unsigned __stdcall FTPAcceptSession(void *data){
    int iSendResult;
    char recvbuf[IN_DEFAULT_BUFLEN];
    int recvbuflen = IN_DEFAULT_BUFLEN;
    int iResult;
    SOCKET ClientSocket = (SOCKET)data;
    // Receive until the peer shuts down the connection

    ClientQuarry NewPacket;

    int err = getpeername(ClientSocket, (struct sockaddr *) &NewPacket.addr, &NewPacket.addr_len);

    if (err != 0) {
        // error, drop the packet.
        closesocket(ClientSocket);
        return 0;
    }

    std::vector<std::string> ToDump;
    int amount = 0;

    do {
        iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
        if (iResult > 0) {
            printf("Bytes received: %d\n", iResult);

            std::string temp = PrependSizePacket(recvbuf);

            amount++;               

            ToDump.push_back(temp); //Add to the buffer.

        }
        else if (iResult == 0)
            printf("Connection closing...\n");
        else{
            printf("recv failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            return 1;
        }

        char* LK = "OK";
        iSendResult = send(ClientSocket, LK, iResult, 0);

        if (iSendResult == SOCKET_ERROR || iSendResult == WSAEFAULT) {
            printf("send failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            return 1;
        }

        printf("Bytes sent: %d\n", iSendResult);
    } while (iResult > 0);

    // shutdown the connection since we're done
    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        return 1;
    }

    closesocket(ClientSocket);

    return 0;
}

DWORD WINAPI FileTransferProtocol(LPVOID lpParam){
    WSADATA wsaData;
    int iResult;

    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;

    struct addrinfo *result = NULL;
    struct addrinfo hints;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    // Resolve the server address and port
    iResult = getaddrinfo(NULL, IN_DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    // Setup the TCP listening socket
    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(result);

    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR) {
        printf("listen failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    for (;;){
        ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ClientSocket == INVALID_SOCKET) {
            printf("accept failed with error: %d\n", WSAGetLastError());
            closesocket(ListenSocket);
            WSACleanup();
            break;
        }

        unsigned threadID;
        HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &FTPAcceptSession,      (void*)ClientSocket, 0, &threadID);
    }

    // shutdown the connection since we're done
    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }

    // cleanup
    closesocket(ClientSocket);
    WSACleanup();

    return 0;
     }

我将程序添加到防火墙,打开端口20001和20000。服务器似乎在connect()请求上超时,但我无法弄清楚原因。

0 个答案:

没有答案