【问题标题】:queue socket connections in CC中的队列套接字连接
【发布时间】:2015-01-08 00:56:54
【问题描述】:

在客户端-服务器架构中,我有一个接受来自客户端的连接的服务器。我希望服务器接受 3 个同时连接,其余连接(如果可用)被搁置,以 FIFO 方式提供服务。 这样做的正确方法是什么?

我想到的一种可能的方法是

创建一个计数器并检查它是否小于 3,接受,在新线程中为客户端提供服务,并增加计数器。当 counter 大于 3 时,只接受套接字描述符并将其保存在队列中。当客户端完成他的工作时,停止线程(例如通过加入)并递减计数器以允许为另一个客户端提供服务。如果队列不为空,则弹出一个套接字描述符,创建一个线程并为客户端提供服务。

感谢您的反馈。

【问题讨论】:

  • 或者您可能希望拥有 3 个工作线程,每个工作线程从队列中读取连接请求。 (一般来说,从客户端的角度来看,接受连接然后保持连接可能不是最好的体验。)
  • 所以你的意思是我把所有连接都放在一个队列中,并且有 3 个工作线程不断弹出和服务?哦,是的,我同意你的看法,但这只是为了练习。
  • 正确。这只是您建议的方案的简化(不再创建/加入线程,也不需要计数器)。
  • 你为什么要故意以这种方式限制你的服务器的有用性?
  • 我明白为什么不需要计数器但是,创建线程呢?怎么不再需要了?当一个线程完成其任务并且客户端断开连接时,我不应该创建一个新线程来代替它吗?

标签: c multithreading sockets


【解决方案1】:

由于listen 函数有一个可以设置的积压,即。它将所有连接保存在一个队列中,当调用accept时,队列中等待的第一个元素实际上被接受,这方面的解决方案如下。

在无限循环中,仅当计数器小于特定数量(同时服务的最大客户端数量)时才接受连接。 声明一个mutex 来保护每次接受连接时递增的计数器。 向 b 声明一个条件变量,用于在线程完成任务时发出信号。 使用该条件变量和互斥锁,如果计数器大于 X,则等待。 当服务于客户端的线程完成其任务时,递减计数器并发出条件信号。因此,无限循环将再次循环并接受已经暂停的客户端。

一个可能的实现可能是:

// global variable 
pthread_mutex_t lock;
pthread_cond_t cv;
int number_of_connected_client = 0;

// a function executed by a thread to handle each user
void *client_thread(void *arg) {

  /* some code */

  // thread is about to finish and return
  // client disconnected --> decrement number of connected clients 
  // signal that a client disconnected
  pthread_mutex_lock(&lock);
  number_of_connected_client-- ;
  pthread_cond_signal(&cv);
  pthread_mutex_unlock(&lock);
  return 0;
}

// infinte loop for accepting connections
while (1) {

  // serve 2 users at a time, queue the rest of the clients in the listen's queue 
  if( number_of_connected_client >= 2 ) {
    pthread_mutex_lock(&lock);      
    pthread_cond_wait(&cv, &lock);
    pthread_mutex_unlock(&lock);
  }

  connfd = accept(listenfd, (struct sockaddr *) NULL, NULL );

  // create a thread and serve the client 
  if( pthread_create( &thread_id , NULL , client_thread, (void*)connfd) <0)
    {
     // error in creating thread
     // do something 
    }

  // client is served --> increment number of connected clients 
  else {
    pthread_mutex_lock(&lock);
    number_of_connected_client ++;
    pthread_mutex_unlock(&lock);
  }

}

这只是一个简单的解决方法,可以让事情为私人测试或硬件等工作......处理这个问题的正确方法是一个池线程,其中工作线程分配了由 Inspired 的评论提供的任务。

【讨论】:

    猜你喜欢
    • 2010-12-15
    • 2016-06-09
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 2012-04-05
    • 2016-07-31
    • 1970-01-01
    • 2013-12-12
    相关资源
    最近更新 更多