本帖最后由 VisualEleven 于 2011-05-15 17:34:14 编辑

解决方案 »

  1.   

    就是利用select函数判断readfds集合是否可读,判断哪些套接字有未决I/O操作,并进一步处理这些IO操作。如果是监听套接字接收到新连接,调用accept返回SOCKET句柄,并将返回SOCKET句柄加入集合中
      

  2.   

    select模型的运用,建议你上网搜一搜,看一看原理,就懂了,不难的
      

  3.   

    大致明白了,可是我现在那个程序,就是用select模型,多个Client连接到sever端后,接收到一个client的数据,本来是要群发给其他client的,现在其他的client不能输入数据,也接受不到数据,只有那个client一直可以send数据,接受数据
    为什么?
      

  4.   

    现在其他的client不能输入数据,也接受不到数据
    ----------------------------------------
    其它的client不能发送数据?是不是你的client的recv阻塞了没有返回还是怎么的?
      

  5.   

    是这样的,我做简单聊天室。本来有一个client1是连着的,但是没有发数据,就是不输入任何聊天的内容,。这时有另一个client2登陆了,client2此时也不能输数据,直到client1在自己窗口输入数据按回车以后,client2就可以输数据了,client1的那些数据却没有发出去,还在自己的输入窗口上,并且再也不能输入与接受了,而client2就可以。我看不出端倪来,第一次用select,不知道哪里出问题了
      

  6.   

    因为你使用的只是read的参数,还有一个write 的参数,不过一般上对于发送数据是不需要的,MSDN上介绍:
    readfds:If listen has been called and a connection is pending, accept will succeed. 
    Data is available for reading (includes OOB data if SO_OOBINLINE is enabled). 
    Connection has been closed/reset/terminated. writefds:If processing a connect call (nonblocking), connection has succeeded. 
    Data can be sent. exceptfds:If processing a connect call (nonblocking), connection attempt failed. 
    OOB data is available for reading (only if SO_OOBINLINE is disabled).
      

  7.   

    本帖最后由 VisualEleven 于 2011-05-16 22:12:36 编辑
      

  8.   

    客户端:在控制台上创建界面,画了三个窗口。即主窗口(显示聊天内容),用户列表窗口(就是显示在聊天室的用户名),最后是输内容的窗口。
    服务端:就是一个黑框框。协议时tcp/ip
    我设想的思路是:服务器打开,等待客户端的连接;客户端运行:(因为在黑框框运行)输入可执行文件,即<.exe文件> <IP> <用户名> ,(用户名在server都记入在一个数组里)连接成功,client就进入界面。server端发送所有登陆的用户名给新登入client,并且给老用户发送新登入用户名(这里就觉得有问题,问题在后面说明),然后就可以相互两天,client将输入内容发给server,server收到后发给所有用户,用户接受了显示在主窗口上。思路就这样子。
    现在的问题就是这样:第一个client登入以后,一切都正常,就是预期那样,用户列表也有了,也可以输入内容。但是如果client1没有输内容,就是不聊天,此时第二个用户登入了,也成功进入界面,但是此时用户列表上一个用户名也没有,也不能输入内容,就是无法响应键盘输入,(比如键盘按了abc,但在输入窗口是没有显示内容的)(但是键盘的内容应该是被保存下来了,为什么呢?下面会提到),而client1就可以输入内容,但是client1输完内容,按回车键,预期是发送过去,应该显示到主窗口上去,可是按完回车键不会有反应了,内容还是在输入窗口上。此时,client2就激活了一样,用户列表上显示了所有用户名,而且也能发送内容,他自身的窗口会有他的内容,而client1窗口接受不到,就好比阻塞了一样,一点反应都没有。(总觉得在client收发端没有处理好,因为新客户什么时候登入没有个准,难道每个client来用一个线程专门来收发?(我现在的想法))if(!(StartLinkServer(argc,argv[1],argv[2],&sClient)))//这个就是实现登入服务器,成功就有socket,就    
    { //是一般的创建,绑定,监听
         cout<<"Becouse of Internet problem,you can not be into the ChatRoom,sorry!"<<endl;
         return;
    }
    IntoChat_Windows();//进入界面函数
    while(1)
    {
            My_Recv(&sClient,pChatMessage,BUFFER_MESSAGE_SIZE);//如果有新用户,server就发/new来做提示
            if(strcmp(pChatMessage,"/new") == 0)
            Flag = true;
    if(Flag)
    {
    ReciveTheUsername(&sClient,pUsername);//就是接受用户名,添加到用户列表上去
    Flag = false;//没有新用户就false
    } SetFocusConsoleWindow(&MessageWindow);//将光标置到输入窗口上
    InputDataConsoleWindow(&MessageWindow,pChatMessage,BUFFER_MESSAGE_SIZE);//输入内容 My_Send(&sClient,pChatMessage,strlen(pChatMessage));//发送输入内容
    if((Ret = My_Recv(&sClient,pChatMessage,BUFFER_MESSAGE_SIZE)) == SOCKET_ERROR)//接受内容
    {
    errornum = WSAGetLastError();
    cout<<"CLient recieve the meaning is failed! ERROR:"<<errornum<<endl;
    closesocket(sClient);
    WSACleanup();
    return;
    }

    ClearConsoleWindow(&MessageWindow);//清空输入窗口内容
    InputChatMessage(&MainWindow,pChatMessage);//显示到主窗口上
    }就是这样