serverSocket 怎样释放失去连接的socket资源?

nevergetwin 2007-08-16 04:47:37
我用的是ServerSocket,底层有一些板子做为客户端,客户端每5秒发送一次连接信息,服务端收到则证明连接正常,否则马上关闭这个连接,报警。
现在发现客户端断开之后(突然断电或者板子重启)服务端相应的socket资源并没有释放,而是过了大概3、4分钟的样子才释放掉,怎样能够马上释放资源呢?
我参考的是网上的代码,如下:
......
procedure TForm1.ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i,j:integer;
begin
j:=-1;
for i:=0 to sessions do
begin
//在原有的客户端连接数组中有中断的客户端连接
if not session[i].CUsed then
begin
session[i].CHandle := Socket.SocketHandle ;//客户端套接字句柄
session[i].CSocket := Socket; //客户端套接字
//session[i].CName := Socket.RemoteHost ; //客户端计算机名称
session[i].CAddress := Socket.RemoteAddress ;//客户端计算机IP
session[i].CUsed := True; //连接数组当前位置已经占用
Break;
end;
j:=i;
end;
if j=sessions then
begin
inc(sessions);
session[j].CHandle := Socket.SocketHandle ;
session[j].CSocket := Socket;
//session[j].CName := Socket.RemoteHost ;
session[j].CAddress := Socket.RemoteAddress ;
session[j].CUsed := True;
end;
Memo1.Lines.Add( "客户端 "+Socket.RemoteAddress + " 连接 ");
end;
......
其实就是怎么样释放session[j].CSocket 这个连接的资源
...全文
1247 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
warmworm 2007-08-23
  • 打赏
  • 举报
回复
看一下TCP协议中协议
在低层系统为每个TCP连接建立了一个定时器,以进行数据的传输


DELPHI中的CLIENTSOCKET SERVERSOCKET本身好象问题不少
到7.0以后好象就再也找不到相应的控件了
目前至少发现了两个问题
1 如果CLIENTSOCKET向一个不可连接地址发起连接,如果连接失败后,会有内存泄漏
2 在接管了SOCKET事件后,即使你处理了ERROR事件,但在某些情况下,SOCKET还是会有异常
而且这个异常在IDE的DEBUG中也无法显示在什么地方出现

目前我要改写程序,把这两个控件给去掉了
bllj 2007-08-22
  • 打赏
  • 举报
回复
以前我遇到过这种情况,其实你无论怎么关闭SOCKET都是没有用的。它有个状态时间,好像就是几分钟系统自己释放。
nevergetwin 2007-08-22
  • 打赏
  • 举报
回复
是这样的,如果客户端也是用delphi编写的就没有问题,现在客户端是一个单片机,用的是精简的TCP/IP协议,只有14k大小,每次重启之后发现收发数据的显示灯闪个不停,这时把服务端关掉,灯就不闪了,说明服务端与客户端在不停的收发包(可能是握手),服务端再开启,客户端马上连入...客户端精简的TCP/IP协议肯定不完整,省略掉的可能是造成这个现象的原因.不管怎样,想解决这个问题,我只能改服务端的程序,让它立即释放资源,让客户端感觉就像第一次连入那样.
这个问题我想大家也是一辈子都不一定遇到的,希望能给点提示也好,谢谢!
constantine 2007-08-21
  • 打赏
  • 举报
回复
这种断并不会让你的client重启后不能链接,每次链接句柄不一样的,你映射的端口信息也会不一样。
我以前测试,故意拔掉网线然后关闭再启动链接一样可以连上,跟你断电是一样的。
你最好跟踪一下代码,看看有没有进入链接。是否是数据那里判断出问题。
并看看是否有socket的错误码。连不上timeout肯定有的是什么原因。
nevergetwin 2007-08-21
  • 打赏
  • 举报
回复
怎么样释放session[j].CSocket 这个连接的资源?
supercc 2007-08-21
  • 打赏
  • 举报
回复
学习
很土 2007-08-21
  • 打赏
  • 举报
回复
使用心跳检测啊
nevergetwin 2007-08-21
  • 打赏
  • 举报
回复
ding
hilson 2007-08-21
  • 打赏
  • 举报
回复
如果是windows平台,直接修改TCP/IP的KeepAliveTime的数值. 系统会帮你回收连接.
记住:编程不可能改变你的人生,快点脱离技术吧,早点实现财务自由!
nevergetwin 2007-08-17
  • 打赏
  • 举报
回复
shutdown我用了,closesocket也试过了,都不行。 uses winsock
建立连接的时候
session[i].CSocket:=Socket; //客户端套接字
把socket赋值给了另一个TCustomWinSocket,然后closesocket(Integer(session[i].CSocket))?
试过了不行啊...
请问楼上的怎么发送心跳包?
nevergetwin 2007-08-17
  • 打赏
  • 举报
回复
哦,现在有个问题,客户端一旦重启就会重连服务端,服务端和客户端会频繁的收发数据包(客户端显示数据收发的LED灯闪个不停),一旦我把服务端关闭再打开,客户端就马上连入,如果不这样客户端就连接不进来。这说明资源不释放,客户端就不能连入,能不能想个办法结束掉这个socket啊...
comanche 2007-08-17
  • 打赏
  • 举报
回复
socket 本身就是不能马上知道释放

客户端每5秒发送一次连接信息,服务端收到则证明连接正常, 这个就是心跳了

现在你可以加入一个判断, if 3 次没收到连接信息 then 关闭连接

session[nn].CSocket.close就可,里面实际用的也是closesocket,这样socket进入TIME_WAIT状态,也是没完全释放倒是,不过这样的socket已经由系统接管,你程序这边是完全释放了的,想立即关闭tcp连接是不可能的,这个是双向握手决定的
newfang 2007-08-16
  • 打赏
  • 举报
回复
发送心跳包~~~
brightyang 2007-08-16
  • 打赏
  • 举报
回复
closesocket(clientsocket)
nevergetwin 2007-08-16
  • 打赏
  • 举报
回复
请给出断开代码,我用Socket.Close; 不管用啊
brightyang 2007-08-16
  • 打赏
  • 举报
回复
按时发送确在线指令,没收到就断开
nevergetwin 2007-08-16
  • 打赏
  • 举报
回复
客户端突然断电或者重启,没有任何关闭消息给服务端,服务端是不知道客户端断开的,那个连接其实还存在,没有释放。
brightyang 2007-08-16
  • 打赏
  • 举报
回复
客户端断开连接自动释放

5,928

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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