用setsockopt 设置了timeout(阻塞模式)出现的问题。(69分)

  • 主题发起人 主题发起人 gohoo
  • 开始时间 开始时间
G

gohoo

Unregistered / Unconfirmed
GUEST, unregistred user!
问题就是放在线程里,
主程序也会因为recvfrom一顿一顿的,
为什么线程里的recvform会影响主程序?
那位大虾指导指导?
 
[:D]代码贴出来,最近俺比较闲,帮忙看看
 
len, flags: integer;
sendbuf: array of byte;
getbuf:array [0..1023]of byte;
wd: wsadata;
h1: integer;
csock: Tsocket;
ih1: icmp_hdr; //icmp头
sa_dest: sockaddr_in;
iph: iphdr; //ip头
//rd: TFDSet;
//pd: Tinaddr;
back:Tdecordbuf;
datalen: integer;
t,t1,t2:dword;
tmout:integer;
begin
if addrstr = '' then exit;
datalen := sizeof(icmp_hdr);
setlength(sendbuf, datalen);
csock := socket(af_inet, sock_raw, ipproto_icmp);
if csock = -1 then
begin
result := -1;//socket建立失败
exit;
end;
{begin}
tmout:=2000;
if not setsockopt(csock,sol_socket,so_rcvtimeo,@tmout,sizeof(tmout))=0 then
begin
result:=-2;//timeout设置失败
closesocket(csock);
exit;
end;
{end}
try
zeromemory(@ih1, sizeof(ih1));
ih1.PType := icmp_echoreq;
ih1.Code := 0;
ih1.icmpseq := 0;
ih1.ICMPid := word(GetCurrentThreadId);
ih1.Checksum := 0;
ih1.seqtime := gettickcount;
ih1.Checksum := word(cksum(@ih1, sizeof(icmp_hdr)));
sa_dest.sin_family := AF_INET;
sa_dest.sin_port := 0;
sa_dest.sin_addr.S_addr := inet_addr(pchar(addrstr));
//=============添加自定义数据=================
copymemory(@sendbuf[0], @ih1, sizeof(ih1));
fillchar(sendbuf[sizeof(ih1)], datalen - sizeof(ih1), 'U');
//==============完毕========================
t1:=gettickcount();
except
result:=-3;//初始化失败
closesocket(csock);
exit;
end;
h1 := sendto(csock, sendbuf[0], length(sendbuf), 0, sa_dest, sizeof(sa_dest));
if h1 = -1 then
begin
result :=-4; //发送数据失败
closesocket(csock);
exit;
end;
len := sizeof(sa_dest);
h2 := winsock.recvfrom(csock, getbuf, sizeof(getbuf), 0, sa_dest, len);
t2 := gettickcount;
if h2 <= 0 then
begin
result:=-5;//接受数据失败
closesocket(csock);
exit;
end;
if h2=WSAETIMEDOUT then
begin
result:=-6;//时间到
closesocket(csock);
exit;
end;
if h2>0 then
begin
try
back := decodebuf(getbuf, h2, t1, self.ThreadID);
if back.icmptype <> no_myicmp then
begin
result:=strtoint(back.timeout);
end
else
begin
result:=-7;//解码失败
closesocket(csock);
exit;
end;
except
result:=-6;
closesocket(csock);
exit;
end;
end;
result:=0;
end
 
终于有人看了。
有些自定义的解码函数无法贴上,东西太多了,也无关大局。
重要的是只要把这个ping放入线程中,主界面就会在timeout设置的时间里停止相应
或者说,在阻塞模式下recvform放在线程里也会影响主进程,无论怎么设置。
如果设置为非阻塞,又不合条件,总不能忙等待吧!
 
不要设置超时
setsockopt(csock,sol_socket,so_rcvtimeo,@tmout,sizeof(tmout))
感觉问题像出在这里
 
根据个人经验,不会出现这种情况。
感觉你的超时设计错误。我是这样写的。
function waitfordt(var insocketid:integer;Timeout:integer):boolean;
var
FDSet: TFDSet;
TimeVal: TTimeVal;
begin
TimeVal.tv_sec := Timeout div 1000;
TimeVal.tv_usec := (Timeout mod 1000) * 1000;
FD_ZERO(FDSet);
FD_SET(insocketid,FDSet);
Result:=select(0,@FDSet,nil,nil,@TimeVal)>0;
end;
 
to truest9:
那个是没错的。我就是用的那个做的timeout;
to dcsdcs;
使用了这个函数,但是没有设置成功,我先找找资料看看。
 
多人接受答案了。
 
后退
顶部