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后的语句
//////////////////////////////////////////////////////
// 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后的语句
表明你没有设置超时。
要设置超时最后一个参数要传入一个
struct timeval {
long tv_sec; // seconds
long tv_usec; // and microseconds
};
结构的地址,并且把里面的两个变量设置为0
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.
因此你就执行不下去了
//////////////////////////////////////////////////////
// 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;
}
下面设断点,看看select有没有返回,2. 你在select里传入的是g_fdRead,
可是在后面却调用了FD_ISSET(*,&g_allSet)我想是不对的,
应该是FD_ISSET(*, &g_fdRead)如果修改了前两个还有问题,可以考虑:
3. 有新连接时
FD_SET(stmp,&g_allSet);
你传入的是一个局部变量,当然由于socket本身是个句柄所以可能函数体结束时依然有效(没试过,我自己也不清楚),如果是由于局部变量被销毁的情况,
可以考虑使用全局数组保存socket
不超过十行你可以看看第1点,显然已经返回第2点:为什么不对的, 感觉改成你的,我的,说实话,我都觉得不对原因:改成你说的,多此一举, select后就剩下了 可读套接字, 所以FD_ISSET(套接字, &g_fdRead); 必然为ture
改成我的:也是句废话,有连接的时候,就已经放在了g_allset里了。
或许第二点有争议。但是依然没有解决问题