如何通过pthread发送套接字ID?

时间:2019-07-05 10:59:41

标签: c++ server pthreads

我在树莓派中有一个服务器,并且想允许多线程。服务器正在运行。客户端在Windows中。 我相信我需要通过pthread_create发送套接字ID,但尚未找到方法。我还有什么需要发送的吗? 最好的方法是什么?

我已经搜索了互联网,其中包括stackoverflow,并尝试了一些解决方案,但是它们没有用。

const int PORT = 12000;
TCPServer tcp;
pthread_t my_thread[MAXCLIENTQUEUE];
int clientID = 0;

int main()
{

    tcp.setup(PORT);    

    int clientQueueSize = 0, threadJoin = 0;
    void *res;

    do {
        socklen_t sosize = sizeof(tcp.clientAddress);
        //realizar o accept
        tcp.newsockfd[clientQueueSize] = accept(tcp.sockfd, (struct sockaddr*) & tcp.clientAddress, &sosize);
        if (tcp.newsockfd[clientQueueSize] == -1)
        {
            cout << "Error accepting -> " << tcp.newsockfd[clientQueueSize] << endl;
            tcp.detach();
        }
        cout << ">- accept: " << strerror(errno) << " / codigo: " << tcp.newsockfd[clientQueueSize] << " - Endereco: " << inet_ntoa(tcp.clientAddress.sin_addr) << endl;
        clientID++;
        cout << ">>> client accepted" << " | Client ID: " << clientID << endl;
        // criar threads
        int ret = pthread_create(&my_thread[clientQueueSize], NULL, messenger, &tcp.newsockfd[clientQueueSize]);
        cout << ">- pthread: " << strerror(errno) << " / codigo: " << ret << endl;
        if (ret != 0) {
            cout << "Error: pthread_create() failed\n" << "thread_n " << my_thread[clientQueueSize] << endl;
            exit(EXIT_FAILURE);
        }
        cout << "thread n " << my_thread[clientQueueSize] << endl;
        clientQueueSize++;
        }
    while (clientQueueSize < MAXCLIENTQUEUE);

    pthread_exit(NULL);

    return 0;
}

服务器接受多个连接,但仅将消息发送到第一个客户端,其他客户端成功连接,但从不接收消息。 我希望服务器能够将消息发送到所有客户端。

1 个答案:

答案 0 :(得分:1)

您必须为所有套接字创建线程。 或者,使用Windows依赖的异步选择方法。

P.S。忘记pthread并使用标准的std::thread

   map<SOCKET,std::string> clients;
   void newclient(SOCKET x)
   {
       for(;;)
       {
       int r = recv(x,...);
       if (r == 0 || r == -1) 
           break;
       }
     // remove it from clients, ensure proper synchronization

   }

   void server()
   {
      SOCKET x = socket(...);
      bind(x,...);
      listen(x,...);
      for(;;)
       {
           auto s = accept(x,...);
           if (s == INVALID_SOCKET)
               break;

           // save to a map, for example, after ensuring sync with a mutex and a lock guard

           m[s] = "some_id";

           std::thread t(newclient,s);
           s.detach();
       }
   }

   int main() // 
   {
          // WSAStartup and other init

          std::thread t(server);
          t.detach();

          // Message Loop or other GUI

   }