1.select模式的socket编程(非阻塞模式)
  select在接到一个网络事件响应以后得到响应的套接字(线程A中),然后把它交给线程池处理(这个时间是很短的,要不一个线程怎么能同时处理几十个套接字的网络事件)。
   线程池中处理该响应需要时间,这时线程A只要把任务交给线程池就会马上返回去再次执行select(线程中循环执行select,来得到网格事件),也许这个时候线程池也许还没有处理完上次线程A交给它的任务,这时线程A在调用select时发现网络事件发生(可能跟上次是同一个事件,因为线程池还没有将上次的事件处理完,它还是存在套接字的那个缓存中),这种情况该怎么处理解决
2.如何确定一个客户端已经与服务器断开(有没有断开的事件),是判断接收数据时返回来的值为-1吗?还是要怎么处理
3.在线程池中如果规定最大线程数100,每个任务时间最少1秒钟(100个任务1秒钟处理完成),现在有3个线程A、B、C每平均1秒钟最少要提交200个任务(线程池只有100个线程,即最少2秒钟才能处理完),而池中没有这么多空闲线程,一般这种情况怎么解决,是把任务放到队列中执行吗
回答以上三个问题,并且方法比较好的,小北另再送上100分,如果只是想接分的请不要回复

解决方案 »

  1.   

    1.有未决任务的连接(Socket)暂时停止select
    2.注册断线消息,在windows当中即使异常断开也会有断线消息,只是响应时间较长
    3.这说明业务处理能力不足,如果机器仍然有可用资源,可以增大线程池的大小,否则说明该机器已经饱和工作,如果要处理更多的业务,应该采用其它方式进行扩展,然后增加硬件设备和提升设备性能等。
      

  2.   

    哦,这个我知道,,我的问题是在不断地发送数到服务器,然后在发送的过程中客户端突然正常断开
    双如closeshock(sock)这样的,有没有事件发生
      

  3.   

    像突然拔网线或掉电,强行CloseSocket等这种,一般还是要交给心跳包来处理
      

  4.   

    如果是正常通讯过程当中closesocket是肯定会有通知的.
      

  5.   

    1.select模式的socket编程(非阻塞模式)
    每次将select中的事件全部拷贝出来,等里面全部的事件都处理完了,再取下一次的事件组
    2.如何确定一个客户端已经与服务器断开(有没有断开的事件),是判断接收数据时返回来的值为-1吗?还是要怎么处理
    可以定时发送环回帧来检测,也就是类似与心跳包,受到响应就认为链接上,多次无法响应就认为断开。
    3.在线程池中如果规定最大线程数100,每个任务时间最少1秒钟(100个任务1秒钟处理完成),现在有3个线程A、B、C每平均1秒钟最少要提交 200个任务(线程池只有100个线程,即最少2秒钟才能处理完),而池中没有这么多空闲线程,一般这种情况怎么解决,是把任务放到队列中执行吗
    放到队列中
      

  6.   

    1,必须要有一个标识,区别不同事件。这样你才能过滤重复事件请求。
    2,TCP等面向链接协议协议处理了这问题。对于 UDP 之类的非链接协议根据需求来做,最多设定间隔使用心跳包(KEEPALIVE)。
    3,线程池当然要配套任务队列,不然偶还能叫线程池么另外 lz 可以去了解 WSAGetLastError() 得到的信息,这对掌握 socket 状态很有帮助
      

  7.   

    谢谢各位指点,这样看来判断客户端断开还是只能根据心跑包来做。我这里有遇到这样一种情况,先连接几个客户端到服务器,发送数,在发送数时就断开连接,结果服务器使用select 时候每次返回都认为这几个套接字有读事件发生,尽管客户端已经断开很久了
      

  8.   

    还有我的第一个问题,虽然楼上兄弟有给出几个办法来,但我认为这样的办法也不是很理想
    1.如果使用标识,每次都得去判断一下这个标识处于什么状态,当要进入select函数时是不是先判断一个套接是处于什么状态再将它放到fd_set结构中去处理吗?这样我感觉出错率比较大,并且可能有很多事件、包会接收不到
    2.如果要判断一个套接是否有未决IO,如果有就不进入下一次监听,这样我感觉更有丢包的可能性