简单的客户端 - 服务器通信不起作用

时间:2015-03-13 13:20:49

标签: c++ sockets winsock2

代码整体上非常简单,但它不起作用,它会抛出char at memory location 0x00EEEE74.的异常,但是我没有可能的地方(据我所知)我的内存界限。

总的来说,我运行两个程序 - 一个客户端和一个服务器,服务器是抛出错误的服务器。 `` 崩溃发生在从服务器函数Receive调用AcceptConnections的程序中,它指向函数的末尾(最后一个括号),并说这是下一个要执行的操作。

以下是两者的代码:

//server-main.cpp
int main()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    Server s("6666");

    WSACleanup();
    return 0;
}

客户主要:

int main()
{
    WSAData wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);

    Client c(SERVER_ADDR, PORT);
    string ToSend("Magshimim Test");
    char buf[1025];
    int bytesRecieved = 0;
    cout << "Bytes sent: " << c.Send((void*)ToSend.c_str(), ToSend.length()) << endl;

    cout << "Recieving message from server..." << endl;
    bytesRecieved = c.Receive((void*)buf, 1024);
    cout << "Bytes Recieved: " << bytesRecieved << endl;
    if(bytesRecieved > 0)
    {
        buf[bytesRecieved] = '\0';
        cout << "Message recieved: " << buf << endl;
    }

    WSACleanup();
    return 0;
}

主要是发送和接收(服务器和客户端相同 - 标志的默认值为0):

int Server::Send(void* buf, int len, int flags)
{
    send(this->_socket, (const char*)&len, sizeof(int), 0); //sending the length of the message
    return send(this->_socket, (const char*)buf, len, flags); //sending the message itself
}

int Server::Receive(void* buf, int maxlen, int flags)
{
    int len_to_recv = 0;
    recv(this->_socket, (char*)&len_to_recv, sizeof(int), 0);
    if (maxlen != 0 && len_to_recv > maxlen) //0 symbolizes unlimited len and we check if there's not too much information
    {
        throw "Receive: Too much information";
    }

    return recv(this->_socket, (char*)buf, len_to_recv, flags);
/*Points here->>>>>*/}

发送Exception的另一个是服务器的c'tor,向下滚动到“AcceptConnections”(由c'tor调用),Receive调用是发出异常的调用。

Server::Server(string Port) : _details(NULL)
{
    struct addrinfo hints;
    this->_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (_socket < 0)
        throw "Invalid socket";
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    if (getaddrinfo(NULL, Port.c_str(), &hints, &this->_details) != 0)
    {
        throw "GetAddrInfo failed";
    }

    if (bind(this->_socket, this->_details->ai_addr, this->_details->ai_addrlen) != 0)
    {
        throw "Bind Unsuccessful";
    }

    freeaddrinfo(this->_details);

    this->AcceptConnections();
}

void Server::AcceptConnections()
{
    if (listen(this->_socket, SOMAXCONN) != 0)
        throw "Listen Unsuccessful";
    char buf[1025];
    char* ans = "Accepted";
    SOCKET client;
    struct sockaddr_in client_addr;
    int addrlen = sizeof(client_addr);

    client = accept(this->_socket, (struct sockaddr*)&client_addr, &addrlen);
    closesocket(this->_socket);
    this->_socket = client;

    cout << "A connection was accepted." << endl; // It prints this

    /*THIS IS WHERE THE PROBLEM OCCURS.
    THIS IS WHERE THE PROBLEM OCCURS.
    IT ENTERS THE FUNCTION, THEN UPON ENDING IT (AFTER THE RETURN), THROWING       AN EXCEPTION*/
    int recvBytes = this->Receive(buf, MY_MAX_LEN); // <<<<<<<<<<<<<<<<<<
    if (recvBytes <= 0)
    {
        throw "Client disconnected";
    }
    this->Send(ans, strlen(ans));

    closesocket(client);
    closesocket(this->_socket);
}

这个代码几乎是在MSDN教程之后的一步一步,但由于某种原因,当我尝试用类来管理它时,它出错了:(

知道为什么吗?

1 个答案:

答案 0 :(得分:0)

无论出现什么其他错误,都必须:

recv(this->_socket, (char*)&len_to_recv, sizeof(int), 0);

你的意思是:

len_to_recv=recv(this->_socket, buf, sizeof(int), 0);

[编辑]以上是废话。

你不应该假设recv()实际上在一次调用中接收到所有4/8字节,(虽然它可能会,但不保证)。还有,字节序?如果您在localhost上运行以进行测试,那么Prolly不是问题,但是..