我是这样做的:
1、把1000个连接用WSAAsyncSelect(....FD_READ|FD_CLOSE)把他们的数据到达定义为同一个事件,
2、然后在这个事件里启动相应连接的数据处理函数就像下面这样//1000个连接数据到达事件
void CTestDlg::OnReceived(WPARAM wParam,LPARAM lParam)
{ if(lParam==FD_READ)
{
m_TempSocketMutex.Lock();   //CMutex变量,以保证m_TempSocket的值正确传递 m_TempSocket=(SOCKET)wParam;
AfxBeginThread(DataDealThread,this); m_TempSocketMutex.Unlock(); //释放
}

if(lParam==FD_CLOSE)
{
...
}

...
}//数据处理线程
UINT DataDealThread(LPVOID lParam)
{
CTestDlg * pDlg=(CTestDlg *)lParam;

SOCKET sock=pDlg->m_TempSocket; char RecvData[MAX_BUFFERSIZE];
memset(RecvData,0,MAX_BUFFERSIZE); //接收消息
int ret=0;
ret=recv(sock,RecvData,MAX_BUFFERSIZE,0);
if(ret<=0)   return 0;
*(RecvData+ret)='\0';
         ...   //数据处理
}说明:每个连接平均10秒发一次数据,也就是说每秒有100个数据到达问题:1、按我上面这样做会漏掉大多数数据,只能接收到部分连接的数据;且没有接收到的数据也触发了这个事件,但不能启动相应的线程,不知何故???      2、如在 “ m_TempSocketMutex.Unlock(); //释放 ” 之前加一句 “ Sleep(50); //等待50毫秒 ” ,所有数据基本可以正确接收,但应用程序界面没法操作,就像死机一样!!      现请教各位高手,有什么好的改进方案或解决办法
      现请教各位高手,有什么好的改进方案或解决办法
      现请教各位高手,有什么好的改进方案或解决办法
      现请教各位高手,有什么好的改进方案或解决办法      先谢谢了!

解决方案 »

  1.   

    1000个联接,WSAAsyncSelect()已经力不从心,虽然它很好用
    但是你除了用完成端口外,没有什么好办法了,关于完成端口,网络版有置顶的
      

  2.   

    现在的情况是不能再改模型呀!,大家有没有好的办法呀!
    还是就是WSAAsyncSelect()能不能处理1000个连接呀???它好像只能同时处理64个
      

  3.   

    WSAAsyncSelect是不行的楼主只有趁机学习一下完成端口了处理楼主这样成百上千个SOCKET唯有完成端口模型,楼主的程序结构要大改了^_^
      

  4.   

    我现在也是被WSAAsyncSelect I/O 苦恼着,我的问题是,在接收文件传输的同时,可以接收简单的字符串的传输。
      

  5.   

    首先,wParam是在栈上还是堆上定义的,要保证其能正确地传到线程中去(至少在线程转换完前必须没有被释放,简单的可以采用全局变量来处理);
    其次,在响应事件时也应该保持同步,防止wParam在传递过程中被改变(在每秒有100个数据到达的情况下);
    再次,负荷这么大,建议可能情况下用IOCP;
      

  6.   

    谢谢各位的发言!是呀!当时没想得那么清楚!应该用完成端口加重叠来处理!但还是不太会!
    不知那位有这么方面的例子(处理很多连接的),可以贡献一下(不要求源代码,只求程序结构框架,毕竟写程序很辛苦!)!!如果我要继续用WSAAsyncSelect(...),针对我提的2个问题大家没没有好的解决办法呀!现在我程序基本上都写完了,现处在测试阶段,发现了这个问题!!!急呀!
      

  7.   

    可以考虑这么干,建50个线程(线程池A),一个线程管几个(如20)个连接,分配下去,全部用WSAEventSelect等待数据,接收到数据后放到处理队列里头去(不直接处理,直接接收下一个),另外放一个线程池(线程池B),专门处理数据。这里要注意的是线程池A和线程池B的数据多少和处理能力要搞平衡,不能处理不了累积在那,也不能让线程池B老是处理不到数据
      

  8.   

    你可以试试这种模型:
    为每个TCP连接创建一个线程,在创建一个队列个一个保护队列的互斥,并创建一个处理数据队列的线程,该线程可以一直运行或在你需要的时候运行,每个TCP的线程受到数据后,去等待互斥,得到互斥后,将数据加入到队列,然后释放互斥;如果处理数据的线程是挂起的,就唤醒他,处理线程首先得到互斥,将队列里所有的数据取出,释放互斥,然后在循环处理已经取出的数据。。
      

  9.   

    你可以为每一个连接 new 你一个数据通讯类
    所有的数据处理在他自己的OnReceived里处理
    可能会好一些:)
      

  10.   

    你这样建立线程太浪费了,应该一次性启动N个线程,然后守侯数据进行处理.
    另外你的界面发生阻塞,是因为你的Sleep(50)将主线程阻塞了,你可否考虑将OnReceived在另外一个线程实现?? MFC SOCKET我用的不多,其实直接使用SOKCET API做的话很简单的,WINDOWS消息模型的SOCKET不好控制,而且有BUG
      

  11.   

    可能的问题:
    1.你的代码无法保证m_TempSocket的正确行
    m_TempSocketMutex.Lock();   //CMutex变量,以保证m_TempSocket的值正确传递 m_TempSocket=(SOCKET)wParam;
    AfxBeginThread(DataDealThread,this); m_TempSocketMutex.Unlock(); //释放因为解锁后,线程可能没有执行完SOCKET sock=pDlg->m_TempSocket;
    解决办法--〉直接把wParam作为参数传入,而不是this,也不用加锁,如果需要访问主线程必须通过PostThreadMessage/PostMessage方法2.你的代码无法保证同一个Socket recv同时只在一个线程执行
    3.你临时创建线程的效率太低
    当然你的发送频率,不会发生问题,但如果每个连接每秒都有很多请求,那肯定有问题
    解决办法-〉预分配n个线程(如:10个),在客户接入时加入一个线程中即可,确保recv在同一个线程执行
    如果你不想大改,仅改掉第一点应该可以解决你目前问题
    当然IOCP很好,但1000个连接用一般模型也完全可以胜任