【问题标题】:How to tell the difference between two clients?如何区分两个客户端?
【发布时间】:2022-01-15 07:19:03
【问题描述】:

我有一个 client 1 发送一些 数据服务器,我想 服务器 传输它dataclient 2 而不是 client 1。有没有办法告诉服务器我们必须使用不同的客户端套接字,如果 client 1 发送数据不发送回 client 1 而是发送到 client 2

当服务器接受 client 1 时,我尝试在其中放入一个列表,但由于某种原因,当服务器接受 client 2 时,它只计为 1 而不是 2 此函数处理来自客户端的缓冲区 无符号 __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);

//接受新客户

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

【问题讨论】:

  • 我认为这里的问题是 List 是 while 内的局部变量。尝试将它放在全局或类范围内,一切都应该工作

标签: c++ networking tcpclient tcpserver


【解决方案1】:

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

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&lt;SOCKET&gt; 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-02
    • 2011-11-25
    • 2012-03-27
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2019-04-02
    相关资源
    最近更新 更多