Winsock2 only create the same socket

Viewed 50

I'm working on a server/client chat room for school.

Everything worked fine until I decided to get inputs of my Clients. Since then, I don't know why but every time I create a new socket, it will always be the same. I've tried to create a new solution, and just create a socket and even their.. sockets are the same.

My test code as simple as that:

#pragma comment (lib, "Ws2_32.lib")
#include <WinSock2.h>
#include <iostream>

int main()
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData))
    {
        return 1;
    }

    // Create Socket
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);

    char a;

    std::cout << "Socket : " << sock << std::endl;
    std::cin >> a;
}

I end up with 4 times the same socket is created:

image

Some time, weirdly it works completely fine, but shortly after it gets back to that.


Edit:

To talk more about the project, I'm not sure how to explain the code without sending 300 lines which I assume isn't the best idea.

So here is my update for the server (yes we're using Polls cause my teacher don't want us to use multithreading for now).

void Server::Update()
{
    do
    {
        WSAPoll(fds_, MAX_CLIENTS, -1);

        for (int i = 0; i < MAX_CLIENTS; ++i)
        {
            if (fds_[i].revents & POLLRDNORM)
            {
                if (i == 0)
                {
                    // Accept
                    AcceptClient(sock_);
                }
                else
                {
                    // Receive
                    ReceiveMsg(fds_[i].fd, receiveBuffer);

                    // Send the message to all clients except the sender
                    for (int j = 0; j < clients_.size(); ++j)
                    {
                        if (clients_[j].socket != fds_[i].fd)
                        {
                            SendMsg(clients_[j].socket, receiveBuffer);
                        }
                    }
                }
            }
            if (fds_[i].revents & POLLHUP)
            {

                closesocket(clients_[i].socket);
                std::cout << "Client with socket " << clients_[i].socket << " disconnected" << std::endl;
                clients_.erase(clients_.begin() + i);
            }
        }
    } while (true);
}

Here is the Accept code:

void Server::AcceptClient(SOCKET sock)
{
    // Client Socket
    SOCKET csock;
    SOCKADDR_IN csin;
    int crecsize = sizeof(csin);

    // Address Buffer
    char adressBuffer[65];

    csock = accept(sock, (SOCKADDR*)&csin, &crecsize);
    if (csock != INVALID_SOCKET)
    {
        std::cout
            << "Client with socket " << csock
            << " connected from " << inet_ntop(AF_INET, &csin.sin_addr, adressBuffer, sizeof(adressBuffer))
            << ":" << csin.sin_port << std::endl;

        clients_.push_back(Client(csock));
        fds_[clients_.size()].fd = csock;
        fds_[clients_.size()].events = POLLIN;
    }
    else
    {
        printError(WSAGetLastError(), __LINE__, __FILE__);
        return;
    }
}

But, by using WSAGetLastError() I know that the error occur client side during the call of connect():

void NetworkClient::ConnectToServer(SOCKET sock, SOCKADDR_IN sin, int recsize)
{
    int sock_err = connect(sock, (SOCKADDR*)&sin, recsize);
    if (sock_err != INVALID_SOCKET)
    {
        std::cout << "Connexion avec le serveur reussie" << std::endl;
    }
    else
    {
        printError(WSAGetLastError(), __LINE__, __FILE__);
        return;
    }
}

So I still end up with the same error, even though my socket is non-blocking.

client can't connect to the server

1 Answers

Unlike on other platforms, where sockets are indexes into a per-process file table, sockets on Windows are kernel objects. When a process exits, any open objects are released automatically, allowing the kernel to reuse them. This is perfectly normal behavior.


UPDATE:

But, by using WSAGetLastError() I know that the error occur client side during the call of connect()

The error code you have shown is 10035 (WSAEWOULDBLOCK), which is normal behavior for a non-blocking connect(). It is NOT an error condition, so don't treat it like one. It simply means the connection operation is in progress. WSAPoll() (or select(), etc) will tell you at a later time when the operation is actually finished, and whether it was successful or not (in your case, the connection is successful, as evident by your server log). This is explained in the connect() documentation:

For connection-oriented, nonblocking sockets, it is often not possible to complete the connection immediately. In such a case, this function returns the error WSAEWOULDBLOCK. However, the operation proceeds.

When the success or failure outcome becomes known, it may be reported in one of two ways, depending on how the client registers for notification.

  • If the client uses the select function, success is reported in the writefds set and failure is reported in the exceptfds set.

  • If the client uses the functions WSAAsyncSelect or WSAEventSelect, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates either success or a specific reason for failure.

Related