socket中select的一个使用例子,select为什么总是返回1

cjy0000 2015-07-03 10:03:02
如下window下客户端用select接收数据的代码。我用的是socket发送http请求。。但是recv两次,明明recv都返回0了,但是select还是返回1,这不相当于超时设定没起作用吗?请知道的指点一下啊。。跪谢!
int socket_open(int IP,int Port,int type)
{
WSADATA Ws;
SOCKET socketId;
struct sockaddr_in serv_addr;
int status;
if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return -1;
}
socketId=socket(AF_INET,SOCK_STREAM,0);
if (socketId == INVALID_SOCKET )
return -1;
/*if((int)socketId<0)
{
printf("[ERROR]Create a socket failed!/n");
return -1;
}*/
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = ntohl(IP);
serv_addr.sin_port = htons((USHORT)Port);
status = connect(socketId,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
if(status != 0)
{
printf("[ERROR]Connecting failed!/n");
closesocket(socketId);
return -1;
}
return socketId;
}

char *GetprotocolHead(string url, string host)
{
static string protocolHead = "GET "+ url;
protocolHead += " HTTP/1.1\r\n";
protocolHead += "Accept: html/text\r\n";
protocolHead += "Accept-Language: zh-cn\r\n";
protocolHead += "Host: ";
protocolHead += host;
protocolHead += ":80\r\n";
protocolHead += "Connection: close\r\n";
protocolHead += "\r\n";
char *char_protocolHead = const_cast<char*>(protocolHead.c_str()); //protocolHead.c_str();
return char_protocolHead;
}

int main()
{ //61.135.169.125:0x3D87A97D百度
//0x0A011E2A是10.1.30.42,百度119.75.217.109:0x774BD96D
int socketId=socket_open(0x3D87A979,80,0); //0xC0A80001是192.168.0.1的十六进制写法。
string url = "http://www.baidu.com/index.html";
string host = "www.baidu.com";
char *protocolHead;
protocolHead = GetprotocolHead(url, host);

send(socketId, protocolHead,strlen(protocolHead),0);
char recvBuf[8192]="/0"; //接收数据缓存4096

fd_set fdSocket; // 所有可用套节字集合
//FD_ZERO(&fdSocket);
//FD_SET(socketId, &fdSocket);
struct timeval timeout={2,0}; // 设置超时
while(true)
{
//char recvBuf[4096]="/0";

FD_ZERO(&fdSocket);
FD_SET(socketId, &fdSocket);
//fd_set fdRead = fdSocket;

int res_select;
res_select = select(0, &fdSocket, NULL, NULL, &timeout);
switch(res_select)
{
case 0 :
printf("time out!\n");
return -1;
//break;
case -1:
printf("select error!\n");
return -1;
//break;
default:
if (FD_ISSET(socketId,&fdSocket))
{
int receive = recv(socketId,recvBuf,8192,0);
if (receive == 0 || (receive == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
{
//closesocket(socketId);
printf("socket close!\n");
break;
}
}
}
}
...全文
619 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
cjy0000 2015-07-07
  • 打赏
  • 举报
回复
引用 9 楼 lianshaohua 的回复:
[quote=引用 7 楼 cjy0000 的回复:] [quote=引用 6 楼 lianshaohua 的回复:] 建议你学习一下select()的用法,
这个问题是为什么,还请明示啊~谢谢[/quote] res_select = select(0, &fdSocket, NULL, NULL, &timeout); 第一个参数有问题[/quote] windows下第一个参数不是没关系吗?
ztenv 版主 2015-07-07
  • 打赏
  • 举报
回复
引用 7 楼 cjy0000 的回复:
[quote=引用 6 楼 lianshaohua 的回复:] 建议你学习一下select()的用法,
这个问题是为什么,还请明示啊~谢谢[/quote] res_select = select(0, &fdSocket, NULL, NULL, &timeout); 第一个参数有问题
ztenv 版主 2015-07-06
  • 打赏
  • 举报
回复
建议你学习一下select()的用法,
dooX8086 2015-07-06
  • 打赏
  • 举报
回复
引用 5 楼 cjy0000 的回复:
[quote=引用 3 楼 dooX8086 的回复:] 两次?? 两次才正确呀。。 select |---> recv 接收数据,(收完了, 服务器会断开) select |---> recv 返回 0 (socket 断开) ..
既然socket都断开了,那为啥select返回值还是1[/quote] socket 断开就会产生 可读与可写 事件. 然后当 recv(socket ...) 就会返回 0 表示 socket 断开 想想服务器在发完数据后就会断开.那么 socket 事件队列就有 [ socket:可读(数据), socket:可读|可写 (断开)] 第一次 select ----> 从socket 事件队列中取出一个件事 ----- socket:可读(数据) |---> recv 接收数据, recv 返回收到的字节数 第二次 select ---- > 从socket 事件队列中取出一个件事 ----- socket:可读|可写(断开) |---> recv 返回 0 第三次 select ---> 没有事件了......等待 / 超时 // 如果发/收完数据只有一次事件, 那么 recv 返回什么好 ? 收到的字节数 ? 还是 0 ?
cjy0000 2015-07-06
  • 打赏
  • 举报
回复
引用 6 楼 lianshaohua 的回复:
建议你学习一下select()的用法,
这个问题是为什么,还请明示啊~谢谢
cjy0000 2015-07-05
  • 打赏
  • 举报
回复
引用 3 楼 dooX8086 的回复:
两次?? 两次才正确呀。。 select |---> recv 接收数据,(收完了, 服务器会断开) select |---> recv 返回 0 (socket 断开) ..
既然socket都断开了,那为啥select返回值还是1
explorer_win 2015-07-03
  • 打赏
  • 举报
回复
每次执行select 前重新设置超时
dooX8086 2015-07-03
  • 打赏
  • 举报
回复
两次?? 两次才正确呀。。 select |---> recv 接收数据,(收完了, 服务器会断开) select |---> recv 返回 0 (socket 断开) ..
pengzhixi 2015-07-03
  • 打赏
  • 举报
回复
你确定你select的第一个参数值是正确的么
cjy0000 2015-07-03
  • 打赏
  • 举报
回复
自己顶一下,求知道的点拨下

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧