socket recv错误代码10053

lulufanfan 2010-08-05 11:15:42
socket是非阻塞模式,在connect的时候,就会报10035的错,后来while循环,一直尝试链接,得到错误代码10056,算是连接上了。send也成功了,但是就是在recv的时候,总是返回10053的错误。在网上查了查,有人说recv之前Sleep一下,在Sleep(10000)的时候,的确是recv到了,但是要是sleep时间变小一点,就又是返回10053错误。因为也是在别人的代码上改的,自己也是糊里糊涂的,代码太多了,就贴一点recv前面的部分吧。

u_long iMode = 1;
ioctlsocket(sock, FIONBIO, &iMode);

while(newlines != 2 && bytesRead != HEADER_BUF_SIZE-1)
{
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
tv.tv_sec = timeout;
tv.tv_usec = 0;

if(timeout >= 0)
selectRet = select(sock+1, &rfds, NULL, NULL, &tv);
else
selectRet = select(sock+1, &rfds, NULL, NULL, NULL);

if(selectRet == 0 && timeout < 0)
{
cout << "selectRet == 0 && timeout < 0" << endl;
return -1;
}
else if(selectRet == -1)
{
cout << "selectRet == 0 && timeout < 0 else" << endl;
return -1;
}

Sleep(10000);
ret = recv(sock, headerPtr, 1,0);


if(ret == -1)
{
cout << "!error: read() in read_header()" << endl;
int error=WSAGetLastError();
cout<<error<<endl;
return -1;
}
.....
}
还有个问题,在recv另外一个网址的时候,倒是可以recv,但是头部内容是
<html><head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
但是我在用Firefox的Live Http headers工具可以看到200的头部。好奇怪的问题。网上说是get请求语句有问题,但为什么一个在sleep之后就正常了,一个却总是400的结果。
我使用两个线程同时访问网址的。
希望大家都来帮帮忙,我本来就不是很懂得,还需要大家多多指教才好。先谢谢各位啦。
...全文
849 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
hukui161 2010-08-07
  • 打赏
  • 举报
回复
洗洗睡了
yutaooo 2010-08-07
  • 打赏
  • 举报
回复


int
Http::nonb_connect(int sockfd, struct sockaddr* sa, int sec) {
int status;
int begin_time = time(NULL);
fd_set wset, xset; /* xset: exceptfds set */
struct timeval timeout;

u_long iMode = 1;
ioctlsocket(sockfd, FIONBIO, &iMode);

if (connect(sockfd, sa, sizeof(struct sockaddr)) == 0) { /* Connect successful immediately */
ioctlsocket(sockfd, FIONBIO, &iMode); /* restore */
return 0;
}

if (WSAGetLastError() != WSAEWOULDBLOCK) { /* WSAEWOULDBLOCK */
cout << "there is something wrong!" << endl;
return -1;
}

FD_ZERO(&wset);
FD_SET(sockfd, &wset);
xset = wset;
timeout.tv_sec = sec;
timeout.tv_usec = 0;
status = select(sockfd + 1, NULL, &wset, &xset, &timeout);

switch (status) {
case -1: // Select error, set the socket as default blocking
ioctlsocket(sockfd, FIONBIO, &iMode);
cout << "2.fcntl() in nonb_connect" << endl;
return -1;
case 0: //Connection timed out.
ioctlsocket(sockfd, FIONBIO, &iMode);
cout << "3.fcntl() in nonb_connect" << endl;
return -1;
default: // Connected successfully.
if (FD_ISSET(sockfd, &wset)) {
/* 这里,用connect(), WSAEISCONN做一次检查 */
if ( (connect(sockfd, sa, sizeof(struct sockaddr)) != 0) &&
(WSAGetLastError() == WSAEISCONN))
{
ioctlsocket(sockfd, FIONBIO, &iMode);
return 0;
}
}
/* TODO: 1. connect() / WSAEISCONN检查失败!!
2. FD_ISSET(sockfd, &xset) 异常发生
*/
ioctlsocket(sockfd, FIONBIO, &iMode);
cout << "4.fcntl() in nonb_connect" << endl;
return -1;
}
}

yutaooo 2010-08-07
  • 打赏
  • 举报
回复
LZ你的短消息已经收到,不过回复系统貌似坏了,只能先贴在这里了。

对winsock不熟悉。参考了一下http://msdn.microsoft.com/en-us/library/ms737625(VS.85).aspx,改了一下你的程序。不知道是否正确,手边没有windows系统做测试。你参考一下吧。

int
Http::nonb_connect(int sockfd, struct sockaddr* sa, int sec) {
int status;
int begin_time = time(NULL);
fd_set wset, xset; /* xset: exceptfds set */
struct timeval timeout;

u_long iMode = 1;
ioctlsocket(sockfd, FIONBIO, &iMode);

if (connect(sockfd, sa, sizeof(struct sockaddr)) == 0) { /* Connect successful immediately */
ioctlsocket(sockfd, FIONBIO, &iMode); /* restore */
return 0;
}

if (WSAGetLastError() != WSAEWOULDBLOCK) { /* WSAEWOULDBLOCK */
cout << "there is something wrong!" << endl;
return -1;
}

FD_ZERO(&wset);
FD_SET(sockfd, &wset);
xset = wset;
timeout.tv_sec = sec;
timeout.tv_usec = 0;
status = select(sockfd + 1, NULL, &wset, &xset, &timeout);

switch (status) {
case -1: // Select error, set the socket as default blocking
ioctlsocket(sockfd, FIONBIO, &iMode);
cout << "2.fcntl() in nonb_connect" << endl;
return -1;
case 0: //Connection timed out.
ioctlsocket(sockfd, FIONBIO, &iMode);
cout << "3.fcntl() in nonb_connect" << endl;
return -1;
default: // Connected successfully.
if (FD_ISSET(sockfd, &wset)) {
/* 这里,用connect(), WSAEISCONN做一次检查 */
if ( (connect(sockfd, sa, sizeof(struct sockaddr)) != 0) &&
(WSAGetLastError() == WSAEISCONN))
{
ioctlsocket(sockfd, FIONBIO, &iMode);
return 0;
}
}
/* TODO: 1. connect() / WSAEISCONN检查失败!!
2. FD_ISSET(sockfd, &xset) 异常发生
*/
ioctlsocket(sockfd, FIONBIO, &iMode);
cout << "4.fcntl() in nonb_connect" << endl;
return -1;
}
}
yutaooo 2010-08-05
  • 打赏
  • 举报
回复

当socket在nonblocking状态下,第一次调用connect()会返回 EINPROGRESS 。表示发起连接,但3次握手没有完成。
后续调用connect()会返回 EALREADY 。表示你已经发起连接了。

应该在第一调用connect()后,调用select()去管理sockfd。当服务端发送SYN+ACK来的时候,select()能够检测到。这时候,对客户端来说,完成连接的建立。

另外应该注意,nonblocking的socket,是有可能在第一调用connect()时,立即完成建立连接的。

看LZ似乎在windows下,但我想,大致概念是一样的。
cattycat 2010-08-05
  • 打赏
  • 举报
回复
select不是这么用的吧,select返回时,那三个fd集合里就有读写事件吧,从那个地方去读写,不要在select后直接调用recv,建议查一下select用法。

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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