winsock fails to connect to localhost

Viewed 327

For my project I am unable to debug the program so i cannot be sure as to why this error occurs.

My server, which is hosted on c# is failing to connect to server on localhost.

Instead of it sending back a "connection" signal to my server, it never connects, I think the code is written well and I can't see any errors, maybe i made a careless mistake somewhere

Also, I HAVE to use gethostbyname instead of getaddrinfo

winsock namespace:

SOCKET WinSock::ConnectToServer(PCHAR IP, USHORT Port)
{
    WSADATA WSA;
    if (WSAStartup(MAKEWORD(2, 0), &WSA))
    {
        SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s != SOCKET_ERROR)
        {
            hostent *Host = gethostbyname(IP);
            if (Host != ERROR)
            {
                SOCKADDR_IN Addr;

                Addr.sin_family = AF_INET;
                Addr.sin_port = htons(Port);
                Addr.sin_addr.s_addr = NULL;

                if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)
                {
                    return s;
                }
            }
        }
    }

    return FALSE;
}

BOOL WinSock::SendData(SOCKET s, PBYTE Packet)
{
    DWORD PacketSize = lstrlenA(PCHAR(Packet));
    if (send(s, PCHAR(&PacketSize), 8, 0) > NULL)
    {
        if (send(s, PCHAR(Packet), PacketSize, 0) > NULL)
        {
            return TRUE;
        }
    }
    return FALSE;
}

main method:

int main()
{
    char key = 1;
    SOCKET S = WinSock::ConnectToServer(0, 55480);
    while(true)
    {
        WinSock:SendData(S, (PBYTE)key);
    }
}
2 Answers
            if (bind(s, PSOCKADDR(&Addr), sizeof(Addr)) > 0)

The description of this code is that it is supposed to connect to a server. But the problem is that bind() does not connect to any server. It only links the socket to a local port. This is what servers that listen on sockets do. This is, presumably, the same port that the server already opened, hence the bind() fails. If the server wasn't listening bind() will, ironically, succeed. But it won't be connect to anything, anyway.

You want to use connect() and not bind().

Additionally, I have to note that if this function creates a socket first, but then fails to establish a connection for this or any other reason it will return an error indication but fail to close the socket, thus leaking a socket descriptor. You must fix this bug, too.

You are not actually making a connection to the server. You are calling bind() to bind the client socket to a local port 55480, but that does not create a connection. You need to instead call connect() to connect the client socket to the remote port 55480.

Also, your SendData() is coded wrong. It is telling send() to send 8 bytes for the PacketSize, but a DWORD is only 4 bytes in size. And send() does not return NULL on failure. And send() is not guaranteed to send all of the requested bytes, so you need to call it in a loop. And it is customary to send multi-byte integers in network byte order (big endian).

Also, you have coded SendData() to expect a null-terminated C-style string, but that is not what your main() is actually passing in to it.

Try something more like this:

bool WinSock::Init()
{
    WSADATA WSA;
    return (WSAStartup(MAKEWORD(2, 0), &WSA) == 0);
}

bool WinSock::Cleanup()
{
    return (WSACleanup() == 0);
}

SOCKET WinSock::ConnectToServer(const char *IP, unsigned short Port)
{
    hostent *Host = gethostbyname(IP);
    if ((Host != NULL) && (Host->h_addrtype == AF_INET)
    {
        SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s != INVALID_SOCKET)
        {
            SOCKADDR_IN Addr = {};

            Addr.sin_family = AF_INET;
            Addr.sin_port = htons(Port);
            Addr.sin_addr.s_addr = * (u_long*) Host->h_addr;

            if (connect(s, PSOCKADDR(&Addr), sizeof(Addr)) != SOCKET_ERROR)
            {
                return s;
            }

            closesocket(s);
        }
    }

    return INVALID_SOCKET;
}

bool WinSock::Close(SOCKET s)
{
    return (closesocket(s) == 0);
}

bool WinSock::SendData(SOCKET s, const void* Data, DWORD DataSize)
{
    const char *ptr = (const char*) Data;

    while (DataSize > 0)
    {
        int numSent = send(s, ptr, DataSize, 0);
        if (numSent == SOCKET_ERROR) return false;
        ptr += numSent;
        DataSize -= numSent;
    }

    return true;
}

bool WinSock::SendData(SOCKET s, const char *Packet)
{
    DWORD PacketSize = lstrlenA(Packet);
    DWORD tmp = htonl(PacketSize);
    if (!SendData(s, &tmp, sizeof(tmp)) return false;
    return SendData(s, Packet, PacketSize);
}
int main()
{
    if (WinSock::Init())
    {
        const char *key = "1";
        SOCKET S = WinSock::ConnectToServer(NULL, 55480);
        if (s != INVALID_SOCKET)
        {
            while (true)
            {
                WinSock:SendData(S, key);
            }
            WinSock::Close(s);
        }
        WinSock::Cleanup();
    }

    return 0;
}
Related