socket的recv函数多次执行后为何会死锁? (200分)

  • 主题发起人 主题发起人 zhfhe
  • 开始时间 开始时间
Z

zhfhe

Unregistered / Unconfirmed
GUEST, unregistred user!
在一个多线程的程序中,线程中的函数ScoketHttp执行大约500次之后,发现 recv()会死锁,不会再执行下一句,有何办法解决?

uses WinSock;
...
Function ScoketHttp(Url:String):String;
var
len,s:integer;
name:sockaddr_in;
he:PHostEnt;
buf:array[0..4095]of char;
str,data:String;
wsd:WSADATA;
begin
WSAStartup($101,wsd);
s:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
he:=gethostbyname('www.ttdown.com');//网站地址
if he=nil then
Exit;

FillChar(name,sizeof(name),0);
name.sin_family:=AF_INET;
name.sin_port:=htons(80);//网站端口
name.sin_addr.S_addr:=PDWORD(PDWORD(he.h_addr)^)^;
if connect(s,name,sizeof(name))<>0 then
begin
closesocket(s);
WSACleanup();
Exit;
end;

str:='HEAD /SoftDown.asp?ID=34589 HTTP/1.1'#13#10'Host:www.ttdown.com'#13#10'Accept: */*'#13#10'Connection: Close'#13#10#13#10;
send(s,PChar(str)^,Length(str),0);
data:='';
while true do
begin
len:=recv(s,buf,sizeof(buf),0);//调试中发现调用函数500多次后此句死锁,不会再执行下一句
if len<1 then
break;
SetString(str,buf,len);
data:=data+str;
end;
closesocket(s);
WSACleanup();

end;
 
阻塞模式的s(用socket函数建立的默认是阻塞模式的)用recv如果没有数据收到当然就不会返回了。
不过这不叫死锁,而是阻塞。
 
能否在阻塞模式中设定超时时间?
 
用WinSocket2是不是可以实现设置超时的功能?
 
建议你用阻塞模式的socket时开线程来recv(indy就是这么干的,而且似乎这么做也是阻塞模式socket的标准做法),这样要设置超时或者同时做其它工作都不成问题了。
 
楼上说得对
用下面的函数可以设置操时
int setsockopt (
SOCKET s,
int level,
int optname,
const char FAR * optval,
int optlen
);

SO_RCVTIMEO int Receive time-out
SO_SNDTIMEO int Send time-out

见win32sdk,需要winsock2支持
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
671
import
I
I
回复
0
查看
833
import
I
I
回复
0
查看
673
import
I
I
回复
0
查看
1K
import
I
I
回复
0
查看
803
import
I
后退
顶部