调用winsocket建立连接后,为什么关不掉连接线程?(急啊,UP有分) (100分)

  • 主题发起人 主题发起人 990
  • 开始时间 开始时间
9

990

Unregistered / Unconfirmed
GUEST, unregistred user!
程序和服务器成功的建立了TCP连接,数据通讯正常。
结束的时候调用了:CloseSocket(Sock); WSACleanup;
但在调试窗口中发现在调用connect时建立的连接线程仍然存在。
[?]这是不是表明占用的资源没有完全释放?
[?]如何关闭这个线程?
[?]如何释放资源?
 
如果是阻塞的socket要等待到超时才能完全释放调。
 
那如何设置winsocket的连接和接收超时呢?
阻塞和非阻塞的我都试过了,都没有释放!
 
如果用控件十比较难控制,建议用api就可以设置有关的参数了,调用shutdown后
再调用closesocket。
 
我就是直接用winsock API做的,shutdown和closesocket我都调用了,
但在watch thread窗口中仍然显示该线程。
哪个API可以设置有关参数?
 
能不能给个简单的例子? 我急啊! 呵呵,解决了,分数全给你啦!
 
那可能是你的线程有问题了。把简单的代码贴出来看看。
 
简单的阻塞测试代码如下:
procedure TForm1.Button2Click(Sender: TObject);
var WSData : TWSAData;
begin
Memo1.Lines.Clear;
memo1.Lines.add('========================== 初始化SOCKT');
if WSAStartup($11,WSData) <> 0 then Memo1.Lines.Add('WSAStartup error')
else Memo1.Lines.Add('WSAStartup ok')
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.Lines.add('========================== 创建套接字');
MySocket := Socket(PF_INET, SOCK_STREAM, 0);
if MySocket = INVALID_SOCKET then Memo1.Lines.Add('Socket Error')
else Memo1.Lines.Add('Socket OK');
memo1.Lines.add('');
end;
procedure TForm1.Button3Click(Sender: TObject);
var server: TSockAddr;
hp: PHostEnt;
data:array[1..100] of byte;
begin

// 建立连接所需要的参数
Server.sin_family := AF_INET;
// 解析服务器IP地址
hp := GetHostByName(PChar(Edit1.Text));
if hp = nil then begin
memo1.Lines.add('GetHostName error');
Exit;
end;
Move(hp^.h_addr^[0],server.sin_addr.S_addr,hp^.h_length);
// 填写服务器端口
Server.sin_port := htons(StrToInt(Edit2.Text));

if Connect(MySocket,Server,sizeof(Server)) < 0 then begin
memo1.Lines.add('Connect error');
Exit;
end
else
memo1.Lines.add('Connect OK');
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
if shutdown(MySocket,2) = 0 then Memo1.Lines.Add('Shutdown ok')
else Memo1.Lines.Add('Shutdown error');
if CloseSocket(MySocket) =0 then memo1.Lines.add('CloseSocket ok')
else memo1.Lines.Add('CloseSocket error');
if WSACleanup = 0 then Memo1.Lines.Add('WSACleanup ok')
else Memo1.Lines.Add('WSAClearnup error')
end;
 
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=1354567
关注一下吧没有人提起来呀!用MODEM打电话利用PC机的耳机和麦克风,自己编程如何实现?
(我知道有现成的软件可以用,但是我想自己实现这个上东西)
QQ:65466700
MAIL: along@b2sun.com
TEL :13802785865
http://b2sun.com
请各位大侠多多指教!

 
呵呵,这个应该没什么关系了,系统会创建这个线程给程序作为socket连接用,直到程序
退出,如果关闭socket后再连接,系统还是利用原先创建的线程而不会再创建新的线程了。
 
对,你说的没错!但我用SPY看了蚂蚁和快车,他们完成一个下载后就关闭了所有的线程。
不知道他们是怎么做的。 还有,如何设置超时??
 
用select可以设置超时。
 
写个例子吧!如何设置连接和接受超时?
 
下面是用c++builder写的,你参考一下。
int ConnSock(const char *HostIp,const unsigned long Port,const long TimeOutUSec)
{
extern int errno;
struct hostent *phe; /* pointer to host information entry */
struct servent *pse; /* pointer to service information entry */
struct protoent *ppe; /* pointer to protocol information entry */
struct sockaddr_in sin; /* an Internet endpoint address */
//unsigned
int SockFd, type = SOCK_STREAM; /* socket descriptor and socket type */
int flags,n,error;
int len;
int ret,rc;
struct fd_set afds;
struct fd_set wfds;
struct timeval tval;
unsigned long blkstate = 0;


memset((char *)&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;

/* Map service name to port number */
if ((sin.sin_port = htons((u_short)Port)) == 0)
{
return(-1);
}
/* Map host name to IP address, allowing for dotted decimal */
if(HostIp!=NULL)
{
if ((phe = gethostbyname(HostIp)) != NULL)
{
memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);
}
else if ((sin.sin_addr.s_addr = inet_addr(HostIp)) == INADDR_NONE)
{
return(-2);
}
}
else
{
sin.sin_addr.s_addr = inet_addr(HostIp);
}
/* Map protocol name to protocol number */
if ((ppe = getprotobyname("tcp")) == 0)
{
return(-3);
}
SockFd = socket(PF_INET, type, ppe->p_proto);
if (SockFd == INVALID_SOCKET)
{
return (-4);
}

if(ioctlsocket(SockFd,FIONBIO,&blkstate) != 0)
{
CloseSocket(SockFd);
return (-5);
}

/* Connect the socket */
if (connect(SockFd, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
CloseSocket(SockFd);
return(-6);
}
}


FD_ZERO(&afds);
FD_SET((unsigned long)SockFd,&afds);
wfds=afds;
tval.tv_sec= TimeOutUSec / 1000;
tval.tv_usec=TimeOutUSec % 1000;

//blkstate = 0;
if(ioctlsocket (SockFd,FIONBIO,&blkstate) != 0)
{
CloseSocket(SockFd);
return (-7);
}

if (select(SockFd+1,&afds,&wfds,NULL,&tval) == 0)
{
CloseSocket(SockFd);
return(-8);
}

if (! FD_ISSET(SockFd,&wfds))
{
/* select error: sockfd not set */
CloseSocket(SockFd);
return(-9);
}

/* restore file status flags */

if(ioctlsocket (SockFd,FIONBIO,&blkstate) != 0)
{
CloseSocket(SockFd);
return (-10);
}
return(SockFd);

}/* End: ConnSock */
 
呵呵,最好的办法是关闭TSOCKET的半关闭选项,也就是没有半等待状态,不等那个最后的
ACK包就关闭
 
<WINDOWS网络编程技术>的第7章第8页(电子版),有关TCP状态的资料,说是很详细。
 
后退
顶部