【问题标题】:WinSock accept() returning 204.204.204.204WinSock accept() 返回 204.204.204.204
【发布时间】:2013-12-14 01:46:46
【问题描述】:

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

苦苦挣扎了很久;我毫不怀疑我犯了一个简单的错误,但我就是看不出来!

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

【问题讨论】:

  • 您将&amp;fromlen 传递给accept()。我认为您只需通过fromlen
  • 检查accept 是否返回成功,因为如果没有,则没有地址可报告。
  • 绝对是迈克的指针。啊,我已将端口设置为非阻塞,然后没有检查成功,我以为它们阻塞了。谢谢史蒂夫!如果你想做一个回答帖子,我会把它标记为正确的。
  • 您没有检查接受的返回值。在尝试向其“发送”任何内容之前,您应该检查“客户端”是否为 -1 (INVALID_SOCKET)。

标签: c++ multithreading networking winsock


【解决方案1】:

正如您在 cmets 中确认的那样:accept 失败了,所以没有要报告的地址。

【讨论】:

    【解决方案2】:

    正如this PCReview thread 中所见,此问题是由于在长度字段中将不正确的值传递给accept 而引起的。在线程的情况下,这是一个空值,在你的情况下,它是一个内存地址 (&amp;fromlen)。

    要修复,请从fromlen 中删除“地址”运算符。

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

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

    编辑

    正如您所提到的,它是一个指针参数。为了大家的兴趣,我将把剩下的答案留在这里。

    【讨论】:

    猜你喜欢
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    相关资源
    最近更新 更多