Home > Enterprise >  How to tell the difference between two clients?
How to tell the difference between two clients?

Time:12-11

I have a client 1 send some data to the server and I want to the server transfer that data to client 2 instead of client 1. Is there any way to tell the server we have to different client sockets, if client 1 send data don't send back to client 1 but send to client 2?

When the server accept the client 1, I try put in it a list but some reason only count as 1 instead of two when server accept the client 2 this function process the buffer from the client unsigned __stdcall ClientSession(void* data) {

char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;

int iResult;
int iSendResult;

SOCKET ClientSocket = (SOCKET)data;

do
{
    
    

        // recv buffer from the client
        iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);

        
        
        if (iResult > 0)
        {
            //iSendResult = send(ClientSocket, recvbuf, iResult, 0);
            iSendResult = send_data(ClientSocket, recvbuf, iResult);
            if (iSendResult == SOCKET_ERROR)
            {
                printf("send failed with error: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }
            //receive from the clients
            printf("Message %.*s\n", iResult, recvbuf);
        }
        else if (iResult == 0)
        {
            printf("Connection closing... \n");
        }
        else
        {
            printf("recv failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }
    
    
} while (iResult > 0);

//ACCEPT COMING CLIENTS

while (ClientSocket = accept(ListenSocket, (sockaddr*)&ClientSocket, NULL))
{


    printf("Accepted");
    if (ClientSocket == INVALID_SOCKET)
    {
        printf("accept failed with errir: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    
    
    
    unsigned threadID;
    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);
    
    // try add new clients to a list
    list<SOCKET> a;

    a.push_back(ClientSocket);
    for (SOCKET i : a) {
        cout << "Hi I'm\n" << ClientSocket;
        cout << "MY SIZE\n" << a.size();
    }
}
enter code here

CodePudding user response:

Your current architecture starts a thread for each client:

HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);

and then the main thread keeps a list of all client sockets, in a local variable:

list<SOCKET> a;
a.push_back(ClientSocket);

then, whenever a thread receives, you have it send to itself:

    iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
        iSendResult = send_data(ClientSocket, recvbuf, iResult);

Sorry to just rephrase, but hopefully that lets you see the issue. There's two main approaches to address this:

  1. Keep most of this, make the list<SOCKET> a; global, add a mutex around it. Change the send_data call to send to all clients in the list a except itself.

  2. Forget the idea of a thread per client. Use non-blocking sockets. Have a mainloop that try to receive from each client and then send to all other clients.

The first approach will look something like:

// lock mutex
for(auto s:a)
{
    if (s != ClientSocket)
    {
        iSendResult = send_data(s, recvbuf, iResult); 
        // error handling
    }
}
// unlock mutex 

and

// lock mutex (same one)
a.push_back(ClientSocket);
for (SOCKET i : a) {
    cout << "Hi I'm\n" << ClientSocket;
    cout << "MY SIZE\n" << a.size();
}
// unlock mutex
  • Related