WinSock accept()返回204.204.204.204

时间:2013-12-14 01:46:47

标签: c++ multithreading networking winsock

尝试创建一个简单的WinSock服务器 - accept()只是保持返回204.204.204.204的IP。我的在线搜索结果显示很多人因为没有给出sockaddr长度(第3次接受()参数而得到此错误,但我已经是。

已经挣扎了很长时间;我毫不怀疑我犯了一个简单的错误,但我无法发现它!

PS。我知道我传递了一些未使用的变量和东西 - 正在进行中的工作:)

Network.h :::

#pragma once
#include <afxwin.h>
#include <string>
#include <Windows.h>
#include <functional>
#include <WinSock2.h>
#include <iostream>
#include "Connection.h"
using namespace std;

#define LISTEN_PORT 20248
#define MAX_CLIENTS 10

typedef struct NETWORK_T
{
    SOCKET c_socket;            // Client Socket
    sockaddr_in addr_in;        // Addr_in
    fd_set set;                 // Used to check if data in socket
    int i;                      // Additional info
} CLIENT, SERVER;

class Network
{
public:
    Network(void);
    ~Network(void);
    void StartListenServer(string port, function<void(Connection)> callback);
    void StopListenServer(void);
    void Connect(string ip, string port);

private:
    bool mServerRunning;
    WSADATA mData;
    SERVER* mServer;

    static UINT ServerThread(LPVOID pParam);

    bool Setup(SERVER* server, WSADATA& data);
    void ServerCloseSocket(NETWORK_T* socket);
    void ServerCloseSocket(SOCKET& socket);
};

Network.CPP :::

#include "Network.h"


Network::Network(void)
{
    mServerRunning = false;
}


Network::~Network(void)
{

}

void Network::StartListenServer(string port, function<void(Connection)> callback)
{
    if(mServerRunning)
        return;         // If server is running we dont want a second

    mServerRunning = true;
    AfxBeginThread(ServerThread, this);
}

void Network::StopListenServer(void)
{
    mServerRunning = false;
}

void Network::Connect(string ip, string port)
{

}

void Network::ServerCloseSocket(NETWORK_T* socket)
{
    shutdown(socket->c_socket, 2);
    closesocket(socket->c_socket);
}

void Network::ServerCloseSocket(SOCKET& socket)
{
    shutdown(socket, 2);
    closesocket(socket);
}

bool Network::Setup(SERVER* server, WSADATA& data)
{
    int res;

    server->addr_in.sin_family = AF_INET;
    server->addr_in.sin_port = htons(LISTEN_PORT);
    server->addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
    res = WSAStartup(0x101, &data);
    if (res != 0)
    {
        cout << "WSAStartup failed.\r\n";
        return false;
    }
    else
    {
        cout << "WSAStartup Version: " << data.wVersion << "\nWSADescription: " << data.szDescription << "\nWSAStatus: " << data.szSystemStatus << "\r\n";
    }
    server->c_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server->c_socket == INVALID_SOCKET)
    {
        cout << "Invalid socket.\r\n";
        return false;
    }
    else if (server->c_socket == SOCKET_ERROR)
    {
        cout << "Socket error.\r\n";
        return false;
    }
    else
        cout << "Server socket established.\r\n";
    res = 1;
    setsockopt(server->c_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&res, sizeof(res));   // Allows the socket to be bound to an address that is already in use
    res = ::bind(server->c_socket, (struct sockaddr*)&server->addr_in, sizeof(struct sockaddr));
    if (res != 0)
    {
        cout << "Socket BIND failed.\r\n";
        return false;
    }
    else
        cout << "Socket bound to port " << LISTEN_PORT << "\r\n";
    res = listen(server->c_socket, MAX_CLIENTS);
    cout << "Server listen mode: " << res << "\nMax clients: " << MAX_CLIENTS << "\r\n";
    res = 1;
    ioctlsocket(server->c_socket, FIONBIO, (u_long*)&res);

    return true;
}

UINT Network::ServerThread(LPVOID pParam)
{
    Network* ntwkPtr = (Network*)pParam;

    ntwkPtr->mServer = new SERVER();

    ntwkPtr->Setup(ntwkPtr->mServer, ntwkPtr->mData);

    SOCKET client;
    SOCKADDR_IN from;
    int fromlen = sizeof(from);

    while(ntwkPtr->mServerRunning)
    {
        char temp[512];
        client = accept(ntwkPtr->mServer->c_socket, (struct sockaddr*)&from, &fromlen); 
        sprintf(temp,"Your IP is %s\r\n",inet_ntoa(from.sin_addr));
        send(client,temp,strlen(temp),0);
        cout << "Connection from " << inet_ntoa(from.sin_addr) <<"\r\n";
        //ntwkPtr->ServerCloseSocket(client);
    }

    ntwkPtr->ServerCloseSocket(ntwkPtr->mServer);
    WSACleanup();

    return 0;
}

2 个答案:

答案 0 :(得分:1)

同样见于this PCReview thread,这个问题是由于在长度字段中将不正确的值传递给accept而导致的。在线程的情况下,这是一个空值,在你的情况下,是一个内存地址(&fromlen)。

要修复此问题,请从fromlen删除“地址”操作符。

作为一个兴趣点,以及来自PCReview线程,其原因是:

  

204是0xCC,这是编译器使用的值   调试版本中未初始化的堆栈变量有助于捕获错误   访问。由于您传递了NULL,因此没有返回任何内容,还有sockAddrIn   没有初始化。

修改

正如您所提到的,它是一个指针参数。为了感兴趣,我会在这里留下其余的答案。

答案 1 :(得分:1)

在评论中确认:accept失败,因此无法报告地址。