如何区分两个客户?

How to tell the difference between two clients?

我有一个 客户端 1 发送一些 数据 服务器 我想服务器数据传输到客户端2而不是客户端1.如果 client 1 发送数据不发送回 client 1 而是发送,有什么方法可以告诉服务器我们必须使用不同的客户端套接字到 客户端 2?

当服务器接受 client 1 时,我尝试在其中放入一个列表,但由于某些原因,当服务器接受 client 时,只算作 1 个而不是 2 个2 此函数处理来自客户端的缓冲区 未签名 __stdcall ClientSession(无效*数据) {

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

//接受新客户

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

您当前的架构为每个客户端启动一个线程:

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

然后主线程在局部变量:

中保存所有客户端套接字的列表
list<SOCKET> a;
a.push_back(ClientSocket);

然后,每当一个线程收到时,您就让它发送给自己:

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

很抱歉只是重新措辞,但希望这能让您看到问题所在。有两种主要方法可以解决这个问题:

  1. 保留其中的大部分内容,使 list<SOCKET> a; 全局化,并在其周围添加一个互斥体。更改 send_data 调用以发送到列表 a 中的所有客户端,但它本身除外。

  2. 忘记每个客户端一个线程的想法。使用非阻塞套接字。有一个主循环尝试从每个客户端接收,然后发送给所有其他客户端。

第一种方法类似于:

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

// 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