select 超时时间设置为0了,为什么还会堵塞啊。
//////////////////////////////////////////////////////
// select.cpp文件#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "WS2_32") // 链接到WS2_32.libclass InitWinSock
{
public:
InitWinSock(BYTE minorVer = 2, BYTE majorVer = 2)
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if(::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~InitWinSock()
{
::WSACleanup();
}
};
#include <windows.h>
#include <process.h>
InitWinSock theSock;FD_SET g_fdRead;FD_SET g_allSet; //全集SOCKET g_sListen;unsigned long _stdcall ThreadFun(void*)
{
while(1)
{ g_fdRead=g_allSet; int nRet = ::select(0, &g_fdRead, NULL, NULL, NULL); printf("%d\n",nRet);
Sleep(500); } //end while return 0;}
int main()
{
USHORT nPort = 9585; // 此服务器监听的端口号 // 创建监听套节字
g_sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
// 绑定套节字到本地机器
if(::bind(g_sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf(" Failed bind() \n");
return -1;
}
// 进入监听模式
::listen(g_sListen, 5); FD_ZERO(&g_allSet); FD_ZERO(&g_fdRead);
FD_SET(g_sListen,&g_allSet); // HANDLE hThread=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,NULL); HANDLE hThread=CreateThread(NULL,0,ThreadFun,0,0,NULL); WaitForSingleObject(hThread,-1); CloseHandle(hThread); return 0;
}代码执行湖,无法执行到select后的语句

解决方案 »

  1.   

     int nRet = ::select(0, &g_fdRead, NULL, NULL, NULL);
    表明你没有设置超时。
    要设置超时最后一个参数要传入一个
    struct timeval {
    long tv_sec; // seconds 
    long tv_usec; // and microseconds 
    };
    结构的地址,并且把里面的两个变量设置为0
      

  2.   

    看最后一个参数的描述
    timeout [in]
    The maximum time for select to wait, provided in the form of a TIMEVAL structure. Set the timeout parameter to null for blocking operations.
      

  3.   

    NULL了就是阻塞该操作 
    因此你就执行不下去了
      

  4.   

    你好,可以再帮忙看看嘛,现在接受不了数据
    //////////////////////////////////////////////////////
    // select.cpp文件
    #include <stdio.h>
    #include <winsock2.h>
    #pragma comment(lib, "WS2_32") // 链接到WS2_32.libclass InitWinSock
    {
    public:
    InitWinSock(BYTE minorVer = 2, BYTE majorVer = 2)
    {
    // 初始化WS2_32.dll
    WSADATA wsaData;
    WORD sockVersion = MAKEWORD(minorVer, majorVer);
    if(::WSAStartup(sockVersion, &wsaData) != 0)
    {
    exit(0);
    }
    }
    ~InitWinSock()
    {
    ::WSACleanup();
    }
    };
    #include <windows.h>
    #include <process.h>
    InitWinSock theSock;FD_SET g_fdRead;FD_SET g_allSet; //全集SOCKET g_sListen;unsigned long _stdcall ThreadFun(void*)
    {
    while(1)
    { g_fdRead=g_allSet; timeval  timeval; timeval.tv_sec=0;
    timeval.tv_usec=0; int nRet = ::select(0, &g_fdRead, NULL, NULL, &timeval); printf("%d\n",nRet); if(nRet<=0)
    {
    Sleep(500);
    continue;
    } //检测是否有新连接,或者有数据传输
    if(FD_ISSET(g_sListen,&g_allSet))
    {
    SOCKET stmp=NULL;
    sockaddr_in sockadd;
    int nLen=sizeof(sockaddr_in); stmp=accept(g_sListen,(sockaddr*)&sockadd,&nLen); FD_SET(stmp,&g_allSet); }
    for(int i=0;i< g_fdRead.fd_count;i++)
    { if(FD_ISSET(g_fdRead.fd_array[i],&g_allSet))
    { SOCKET stmp=NULL;
    sockaddr_in sockadd;
    int nLen=sizeof(sockaddr_in);
    char buf[200];
    ZeroMemory(buf,sizeof(buf));
    recv(g_fdRead.fd_array[i],buf,sizeof(buf),0); printf("接受数据为:%s\n",buf);
    }
    }
    Sleep(500); } //end while
    return 0;}
    int main()
    {
    USHORT nPort = 9585; // 此服务器监听的端口号 // 创建监听套节字
    g_sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(nPort);
    sin.sin_addr.S_un.S_addr = INADDR_ANY;
    // 绑定套节字到本地机器
    if(::bind(g_sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
    printf(" Failed bind() \n");
    return -1;
    }
    // 进入监听模式
    ::listen(g_sListen, 5); FD_ZERO(&g_allSet); FD_ZERO(&g_fdRead);
    FD_SET(g_sListen,&g_allSet); // HANDLE hThread=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,NULL); HANDLE hThread=CreateThread(NULL,0,ThreadFun,0,0,NULL); WaitForSingleObject(hThread,-1); CloseHandle(hThread); return 0;
    }
      

  5.   

    1. 首先可以在int nRet = ::select(0, &g_fdRead, NULL, NULL, &timeval);
    下面设断点,看看select有没有返回,2. 你在select里传入的是g_fdRead,
    可是在后面却调用了FD_ISSET(*,&g_allSet)我想是不对的,
    应该是FD_ISSET(*, &g_fdRead)如果修改了前两个还有问题,可以考虑:
    3. 有新连接时
     FD_SET(stmp,&g_allSet);
    你传入的是一个局部变量,当然由于socket本身是个句柄所以可能函数体结束时依然有效(没试过,我自己也不清楚),如果是由于局部变量被销毁的情况,
    可以考虑使用全局数组保存socket
      

  6.   

    第三点是不对的, 你看windows下FD_SET的源码, 
    不超过十行你可以看看第1点,显然已经返回第2点:为什么不对的, 感觉改成你的,我的,说实话,我都觉得不对原因:改成你说的,多此一举, select后就剩下了 可读套接字, 所以FD_ISSET(套接字, &g_fdRead);  必然为ture
    改成我的:也是句废话,有连接的时候,就已经放在了g_allset里了。
    或许第二点有争议。但是依然没有解决问题