当前位置:  技术问答>linux和unix

菜鸟求救:多线程 多socket

    来源: 互联网  发布时间:2017-02-19

    本文导语:  大家好,看了一份源代码,就是mjpeg-streamer,用来做视频监控的,B/S架构。 服务器端开启10个线程,每个线程开了50个socket监听,每个socket都用select来处理请求,对于已accept的请求,再启动一个新线程来发送数据。 ...

大家好,看了一份源代码,就是mjpeg-streamer,用来做视频监控的,B/S架构。

服务器端开启10个线程,每个线程开了50个socket监听,每个socket都用select来处理请求,对于已accept的请求,再启动一个新线程来发送数据。


小弟对网络编程还不是很熟悉,请问这样可行么?还是我对代码理解有误
代码大致如下(注释部分是我自己写的),求救啊:
int output_run(int id)
{
  /* create thread and pass context to thread function */
  pthread_create(&(servers[id].threadID), NULL, server_thread, &(servers[id]));//参数为servers[id]
  pthread_detach(servers[id].threadID);

  return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////分割线
/******************************************************************************
Description.: Open a TCP socket and wait for clients to connect. If clients
              connect, start a new thread for each accepted connection.
Input Value.: arg is a pointer to the globals struct
Return Value: always NULL, will only return on exit
******************************************************************************/
void *server_thread( void *arg ) {
  int on;
  pthread_t client;
  struct addrinfo *aip, *aip2; //IP地址,端口等
  struct addrinfo hints;
  struct sockaddr_storage client_addr;
  socklen_t addr_len = sizeof(struct sockaddr_storage);
  fd_set selectfds;
  int max_fds = 0;
  char name[NI_MAXHOST];
  int err;
  int i;

  context *pcontext = arg;
  pglobal = pcontext->pglobal;

  /* set cleanup handler to cleanup ressources */
  pthread_cleanup_push(server_cleanup, pcontext);

  bzero(&hints, sizeof(hints));
  hints.ai_family = PF_UNSPEC;
  hints.ai_flags = AI_PASSIVE;
  hints.ai_socktype = SOCK_STREAM;//使用tcp协议

  snprintf(name, sizeof(name), "%d", ntohs(pcontext->conf.port));
  if((err = getaddrinfo(NULL, name, &hints, &aip)) != 0) {
    perror(gai_strerror(err));
    exit(EXIT_FAILURE);
  }

  for(i = 0; i sd[i] = -1;

  /* open sockets for server (1 socket / address family) */
  i = 0;
  for(aip2 = aip; aip2 != NULL; aip2 = aip2->ai_next)
  {
  //打开设备符
    if((pcontext->sd[i] = socket(aip2->ai_family, aip2->ai_socktype, 0)) sd[i], SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) ai_family == AF_INET6 && setsockopt(pcontext->sd[i], IPPROTO_IPV6, IPV6_V6ONLY,
                  (const void *)&on , sizeof(on)) sd[i], aip2->ai_addr, aip2->ai_addrlen) sd[i] = -1;
      continue;
    }

    //监听
    if(listen(pcontext->sd[i], 10) sd[i] = -1;
    } else {
      i++;
      if(i >= MAX_SD_LEN) {
        OPRINT("%s(): maximum number of server sockets exceeded", __FUNCTION__);
        i--;
        break;
      }
    }
  }

  pcontext->sd_len = i;

//htons字节顺序转换函数
  if(pcontext->sd_len conf.port));
    closelog();
    exit(EXIT_FAILURE);
  }

  /* create a child for every client that connects */
  while ( !pglobal->stop ) {
    //int *pfd = (int *)malloc(sizeof(int));
    cfd *pcfd = malloc(sizeof(cfd));

    if (pcfd == NULL) {
      fprintf(stderr, "failed to allocate (a very small amount of) memoryn");
      exit(EXIT_FAILURE);
    }

    DBG("waiting for clients to connectn");

    do {
      FD_ZERO(&selectfds);

      for(i = 0; i sd[i] != -1) {
          FD_SET(pcontext->sd[i], &selectfds);

          if(pcontext->sd[i] > max_fds)
            max_fds = pcontext->sd[i];
        }
      }
//select管理设备,防止阻塞
      err = select(max_fds + 1, &selectfds, NULL, NULL, NULL);

      if (err fd = accept(pcontext->sd[i], (struct sockaddr *)&client_addr, &addr_len);//accept连接,返回一个新的
        //socket描述符,并传递到下面的pthread_create(&client, NULL, &client_thread, pcfd)中,供传递使用
        //也即send的参数中使用的socket描述符
        pcfd->pc = pcontext;

        /* start new thread that will handle this TCP connected client */
        DBG("create thread to handle client that just established a connectionn");

        if(getnameinfo((struct sockaddr *)&client_addr, addr_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) == 0) {
          syslog(LOG_INFO, "serving client: %sn", name);
        }
//新建一个新的线程
        if( pthread_create(&client, NULL, &client_thread, pcfd) != 0 ) {
          DBG("could not launch another client threadn");
          close(pcfd->fd);
          free(pcfd);
          continue;
        }
        pthread_detach(client);
      }
    }
  }

  DBG("leaving server thread, calling cleanup function nown");
  pthread_cleanup_pop(1);

  return NULL;
}


|
嵌入式方面的网络开发一般写的都比较次,个人感觉.

这代码很明显的惊群现象, 看它说arg是全局变量, 每个线程都用同一个域名做bind,还用了reuseaddr,太恶心了。

应该一个线程做监听,然后每个线程select一个管道,做异步的连接分发。

    
 
 

您可能感兴趣的文章:

  • 菜鸟问个多线程编程的问题,请各位大大赐教!
  • (菜鸟基础问题)关于内核线程
  • 菜鸟问题:怎样用g++编译多线程程序?
  • 有关Linux下开发程序--上万个线程问题。菜鸟问(来者有分,谢谢大家)
  • 菜鸟一问:请问怎么启动线程?高手请指教
  • 菜鸟的多线程简单问题~~~
  • (菜鸟飞飞)问个关于线程互斥的问题
  • Linux多线程菜鸟问题
  • 菜鸟Linux 线程问题
  • 关于多线程的菜鸟问题?在线等待,急!
  • 【linux菜鸟第一帖】:请问多线程开发,为何不能设置多个线程的优先级问题?
  • (菜鸟飞飞)问个多线程的程序的问题
  • 菜鸟求助多线程并发服务器
  • 紧急!菜鸟求救!把swap分区改为primary就不能进入系统!在线等待。。。
  • javabean的存放目录。(菜鸟求救)
  • linux菜鸟的安装问题求救!
  • 谁有安装cc时所需的系列号?菜鸟求救
  • 菜鸟求救:有关runclient的问题!
  • 菜鸟求救
  • ??菜鸟求救!!
  • 菜鸟求救,linux问题
  • 菜鸟求救: 到底应该如何学习java???
  • 菜鸟求救!关于Servlet编译问题!
  • 求救: 菜鸟安装 RedHet 7.2 !! 请大家一定帮帮忙! 一定给分!
  • 。。菜鸟求救。。。如何把光碟上的Linux装到虚拟机上。。。?
  • javabean的存放目录。(菜鸟求救) iis7站长之家
  • 疯狂菜鸟绝望求救
  • 菜鸟求救,请大家帮忙,非常感谢.............
  • 紧急求救,地地道道的菜鸟!
  • 求救啊!!!很简单的问题,请大家帮帮菜鸟我(系列之2)
  • 俺是个菜鸟 linux害了我 求救呀
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • ----菜菜鸟第三问:-菜鸟菜问:JAVA如何求 根号、开次方? -----
  • 菜鸟问一个关于j2ee的菜鸟问题
  • 怎样从一个菜鸟级的java programer升级到一个菜鸟级的java developer
  • 一个连菜鸟都算不上的菜鸟
  • 菜鸟求问菜鸟问题 ,域名绑定
  • ===菜鸟系列===:写过毕业论文的前辈请进!!!菜鸟散分啦!!!!
  • gcc问题---菜鸟发问之一,老大们帮忙啊!!菜鸟分不多,只好给这点了,对不起!!
  • 菜鸟又来问菜鸟问题了
  • 菜鸟的Linux练习疑问……
  • 菜鸟刚学jsp,还不知道怎么和sql server2000的数据库相连,我已经把odbc配好了,谁能给我一段和数据库相连的并显示所有数据的代码!菜鸟
  • 菜鸟提问,我怎么装redhat7。1
  • 菜鸟写的俄罗斯方块,请多多批评!
  • 小问题,你一定能够帮忙!——菜鸟请求帮忙!!
  • 一个菜鸟的请求: 哪位前辈能给晚辈讲讲“匿名类”
  • ※菜鸟送分之一※ Red Hat Linux 的最高版本是多少?
  • 菜鸟问题:在Java中如何接收从键盘输入的字符串?
  • ★菜鸟问:怎么在RED HAT LINUX7.2中用169上网??
  • 菜鸟提问:包是什么概念?
  • 菜鸟问题~~快点进来拿分
  • 菜鸟菜问题1


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3