在一个线程中管理多个socket

举报
张俭 发表于 2023/12/29 15:33:28 2023/12/29
【摘要】 在最基本的模型中,服务器一次只处理一个客户端,如果你想要实现一个可以扩展的服务器的话,那么该如何去做呢最简单的扩展方式是为每个客户端产生一个新的线程,但不推荐这种方式,因为:1.线程比较难以编码,调试,而且有些时候,它们会产生不可预测的结果2.切换上下文的消耗3.对于大量的客户端,不可扩展4.可能会引起死锁Select()使用Linux中的select命令1.select命令允许监控多个fi...

在最基本的模型中,服务器一次只处理一个客户端,如果你想要实现一个可以扩展的服务器的话,那么该如何去做呢
最简单的扩展方式是为每个客户端产生一个新的线程,但不推荐这种方式,因为:
1.线程比较难以编码,调试,而且有些时候,它们会产生不可预测的结果
2.切换上下文的消耗
3.对于大量的客户端,不可扩展
4.可能会引起死锁

Select()

使用Linux中的select命令

1.select命令允许监控多个file descriptors, 等待其中一个file descriptor可用
2.如果sockets中有一个要提供信息,select命令将会提供信息
3.Select就像中断处理那样工作,当如果有file descriptor传递信息时使用

slect使用的数据结构是 fd_set, 这包含了一个活动要监视的所有file descriptor,主要的方法有四个

fd_set readfds;

//Clear an fd_set
FD_ZERO(&readfds);

//Add a descriptor to an fd_set
FD_SET(master_sock, &readfds);

//Remove a descriptor from an fd_set
FD_CLR(master_sock, &readfds);

//If something happened on the master socket, then its an incoming connection
FD_ISSET(master_sock, &readfds);

实现代码:

#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h>
#include <errno.h>
#include <unistd.h> //close
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/sockets.h>
#include <netinet/in.h>
#include <sys/time.h> //FD_SET FD_ISSET, FD_ZERO macros

#define TRUE 1
#define FALSE 0
#define PORT 8888
int main(int argc, char * argv[]) {
  int opt = TRUE;
  int master_socket, addrlen, new_socket, client_socket[30], max_clients = 30, activity, i, valread, sd;
  int max_sd;
  struct sockaddr_in address;

  char buffer[1025];
  
  //set of socket descriptors
  fd_set readfds;

  //a message
  char *message = "ECHO Daemon v1.0 \r\n";
  
  //初始化所有client_socket为0
  for(i=0; i<max_clients;i++) {
    client_socket[i] = 0;
  }
  if( (master_socket = socket(AF_INET,  SOCK_STREAM, 0 )
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。