简体   繁体   English

如何选择数据并将其发送到特定的Winsock客户端

[英]How to select and send data to a specific winsock client

I have used C++ & Winsock2 to create both server and client applications. 我已经使用C ++和Winsock2创建服务器和客户端应用程序。 It currently handles multiple client connections by creating separate threads. 当前,它通过创建单独的线程来处理多个客户端连接。

Two clients connect to the server. 两个客户端连接到服务器。 After both have connected, I need to send a message ONLY to the first client which connected, then wait until a response has been received, send a separate message to the second client. 两者都连接后,我只需要向连接的第一个客户端发送一条消息,然后等待直到收到响应,再向第二个客户端发送一条单独的消息。 The trouble is, I don't know how I can target the first client which connected. 问题是, 我不知道如何定位连接的第一个客户端。 The code I have at the moment accepts two connections but the message is sent to client 2. 我目前拥有的代码接受两个连接,但是消息发送到客户端2。

Can someone please give me so ideas on how I can use Send() to a specific client? 有人可以给我一些想法,以便我了解如何使用Send()到特定客户端吗? Thanks 谢谢

Code which accepts the connections and starts the new threads 接受连接并启动新线程的代码

        SOCKET TempSock = SOCKET_ERROR;                 // create a socket called Tempsock and assign it the value of SOCKET_ERROR
        while (TempSock == SOCKET_ERROR && numCC !=2)   // Until a client has connected, wait for client connections
        {
            cout << "Waiting for clients to connect...\n\n";

            while ((ClientSocket = accept(Socket, NULL, NULL))) 
            {
            // Create a new thread for the accepted client (also pass the accepted client socket).
            unsigned threadID;
            HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);
            }
        }

ClientSession() ClientSession()

    unsigned __stdcall ClientSession(void *data)
    {
        SOCKET ClientSocket = (SOCKET)data;

        numCC ++; // increment the number of connected clients

        cout << "Clients Connected: " << numCC << endl << endl; // output number of clients currently connected to the server

        if (numCC <2) 
            {
                cout << "Waiting for additional clients to connect...\n\n";
            }   

        if (numCC ==2)
        {
        SendRender();       // ONLY TO CLIENT 1???????????


            // wait for client render to complete and receive Done message back
            memset(bufferReply, 0, 999);                                // set the memory of the buffer
            int inDataLength = recv(ClientSocket,bufferReply,1000,0);   // receive data from the server and store in the buffer
            response = bufferReply;                                     // assign contents of buffer to string var 'message'

            cout << response << ". " << "Client 1 Render Cycle complete.\n\n";

            SendRender(); // ONLY TO CLIENT 2????????????
        }
        return 0;
    }

Sendrender() function (sends render command to the client) Sendrender()函数(将渲染命令发送到客户端)

    int SendRender()
    {
        // Create message to send to client which will initialise rendering
            char *szMessage = "Render";

            // Send the Render message to the first client
            iSendResult = send(ClientSocket, szMessage, strlen(szMessage), 0);      // HOW TO SEND ONLY TO CLIENT 1???
            if (iSendResult == SOCKET_ERROR) 
        {
                // Display error if unable to send message
                cout << "Failed to send message to Client " << numCC << ": ", WSAGetLastError();
                closesocket(Socket);
                WSACleanup();
                return 1;
        }
            // notify user that Render command has been sent
            cout << "Render command sent to Client " << numCC << endl << endl;

            return 0;
    }

You can provide both a wait function and a control function to the thread by adding a WaitForSingleObject (or WaitForMultipleObjects) call. 通过添加WaitForSingleObject(或WaitForMultipleObjects)调用,可以为线程提供wait函数和control函数。 Those API calls suspend the thread until some other thread sets an event handle. 这些API调用将挂起线程,直到其他线程设置了事件句柄为止。 The API return value tells you which event handle was set, which you can use to determine which action to take. API返回值告诉您设置了哪个事件句柄,可以用来确定要采取的操作。

Use a different event handle for each thread. 为每个线程使用不同的事件句柄。 To pass it in to a thread you will need a struct that contains both the event handle and the socket handle you are passing now. 要将其传递给线程,您将需要一个同时包含事件句柄和您现在传递的套接字句柄的结构。 Passing a pointer to this struct into the thread is a way to, in effect, pass two parameters. 实际上,将指向此结构的指针传递给线程是一种传递两个参数的方法。

Your main thread will need to use CreateEvent to initialize the thread handles. 您的主线程将需要使用CreateEvent来初始化线程句柄。 Then after both sockets are connected it would set one event (SetEvent), triggering the first thread. 然后,在连接两个套接字后,它将设置一个事件(SetEvent),触发第一个线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM