socket select和线程池处理数据

C语言 码拜 9年前 (2015-09-27) 1634次浏览
 

因为数据的收发比较频繁,数据也相对较大,所以想用select+线程池来处理数据。

但是我有一个问题:

服务端,如果是使用这样的模式:

if(select ok)

{

   create a thread;//thread 处理accept和recv

}

还是

if(select ok)

{

   if(accept ok)

   {

      create a thread;//thread 处理recv

   }

}

上面两种是我自己的想法,哪种好些?还是都不行呢?

#1

10分

首先,你这里不管那种方法都没有开启线程池的,
只是一个客户上来之后,开一个线程来处理这个客户的各种业务逻辑而已
//这个才是正确的,上个那种方法错的太离谱了
//select函数只是为了轮询有没有准备好的套接子而已!
//它是对一个服务端来管理所有客户端连上来的套接字的!
if(select ok)
{
   if(accept ok)
   {
      create a thread;//thread 处理recv
   }
}
#2

回复1楼:

我上面没说清楚,我是在有创建线程池的,应该是wake up a thread而不是create。

呵呵,谢谢,目前是打算直接判断是否存在accept来唤醒线程,不使用select

#3

10分

回复2楼:

 结贴是个号好习惯哦!亲

#4

回复3楼:

我还有问题啊。

如果是UDP的服务端,多客户端发送数据,服务端不考虑回复客户端。

需要使用select吧。因为如果直接recv的话,我感觉逻辑有问题啊

#5

10分

回复4楼:

是的!

#6
因为recvfrom,我觉得没办法判断一个客户端的数据是否接收完成。

recvfrom();      //假设我设置1k的缓冲区,但是实际数据为1.5k,那么我就需要两次recv才可 

                //以完成接收动作,但是没办法确认每次不同客户端上行都需要几次

但是我使用

while(select() == TRUE)

{

     recvfrom();      //这样我可以一次接收,只针对一个客户端的上行,没问题吧?

}

#7

刚查到资料说UDP并发select也不好,那我还是在研究研究。

先不结贴

#8

10分

回复6楼:

udp是无序的,数据长了要分片。

针对多客户端发过来的udp,用select或者只用recvfrom都是可以的,只要在自己的包头中标志好相关信息,比如是否分片,属于哪个。

并不是说用了select就能自动保证一个客户端的上行了

#9

回复8楼:

是的,还是全部接收下来后在分析处理。

关了,谢谢两位了

#10
首先,对于listenfd,使用FD_SET加入到fdset中,

然后,使用一个数组connfds保存所有简历的socket fd,

最后,在服务端程序的main函数中,有个while循环,逻辑如下:

while(true)

{

       if(FD_ISSET(listenfd, fdset)

       {

                conn_fd = accept(…);

                connfds[i] = conn_fd;

                FD_SET(conn_fd, fdset);

       }

       for(遍历connfds数组)

      {

               if(FD_SET(connfds[I], fdset)

               {

                        唤醒线程池中的一个空闲线程;

               }

       }

}

      

不知道上面的逻辑可以不?

谢谢

#11
上面的回复忘了加select调用,不好意思。

首先,对于listenfd,使用FD_SET加入到fdset中,

然后,使用一个数组connfds保存所有简历的socket fd,

最后,在服务端程序的main函数中,有个while循环,逻辑如下:

while(true)

{

      ret = select(….fdset);

       if(FD_ISSET(listenfd, fdset)

       {

                conn_fd = accept(…);

                connfds[i] = conn_fd;

                FD_SET(conn_fd, fdset);

                if(–ret <= 0)

                        continue;

       }

       for(遍历connfds数组)

      {

               if(FD_SET(connfds[I], fdset)

               {

                        唤醒线程池中的一个空闲线程;

               }

       }

}

      

不知道上面的逻辑可以不?

谢谢 


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明socket select和线程池处理数据
喜欢 (0)
[1034331897@qq.com]
分享 (0)