1

Trying to create a simple WinSock server - accept() just keeps returning the IP of 204.204.204.204. My online search results show a lot of people get this error from not giving a sockaddr length (3rd accept() param) but I already am.

Been struggling for a long time; I have no doubt that I have made a simple mistake but I just can't spot it!

PS. I know I have a few unused variables being passed about and stuff - Work in progress :)

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;
}
jProg2015
  • 1,098
  • 10
  • 40
  • You're passing `&fromlen` to `accept()`. I think you need to be passing just `fromlen`. –  Dec 14 '13 at 01:54
  • 1
    Check that `accept` has returned success, because if not there's no address to report. – Steve Jessop Dec 14 '13 at 01:57
  • Its definitely a pointer Mike. Ah I had set the ports to non blocking then wasn't checking for success, I thought they were blocking. Thanks Steve! If you want to do an Answer post I'll mark it correct. – jProg2015 Dec 14 '13 at 02:04
  • You aren't checking the return value from accept. You should check to see if "client" is -1 (INVALID_SOCKET) before attempting to "send" anything to it. – selbie Dec 14 '13 at 02:14

2 Answers2

1

As also seen in this PCReview thread, this issue caused by passing an improper value to accept in the length field. In the case of the thread this was a null value, in your case it is a memory address (&fromlen).

To fix, remove the "address of" operator from fromlen.

As a point of interest, and also from the PCReview thread, the reason for this is:

204 is 0xCC, which is the value that the compiler uses for uninitialized stack variables in debug builds to help catch bad accesses. Since you passed NULL, nothing was returned, and sockAddrIn was uninitialized.

Edit

As you have mentioned, it is a pointer parameter. I'll leave the rest of the answer here for the sake of interest.

Elliot Robinson
  • 1,384
  • 7
  • 16
  • 1
    In MSVC debug mode there are some special value that helps debugging easier which programmers should know http://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new – phuclv Dec 14 '13 at 02:26
1

As you confirm in comments: accept was failing, so there is no address to report.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699