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 这个连接的资源
...全文
1156 18 打赏 收藏 转发到动态 举报
写回复
用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
  • 打赏
  • 举报
回复
客户端断开连接自动释放
主要特性Java 语言是简单的:Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧。Java 语言是面向对象的:Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。Java语言是分布式的:Java 语言支持 Internet 应用的开发,在基本的 Java 应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括 URL、URLConnection、SocketServerSocket 等。Java 的 RMI(远程方法激活)机制也是开发分布式应用的重要手段。Java 语言是健壮的:Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。Java语言是安全的:Java通常被用在网络环境中,为此,Java 提供了一个安全机制以防恶意代码的攻击。除了Java 语言具有的许多安全特性以外,Java 对通过网络下载的类具有一个安全防范机制(类 ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类 SecurityManager)让 Java 应用设置安全哨兵。Java 语言是体系结构中立的:Java 程序(后缀为 java 的文件)在 Java 平台上被编译为体系结构中立的字节码格式(后缀为 class 的文件),然后可以在实现这个 Java 平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。Java 语言是可移植的:这种可移植性来源于体系结构中立性,另外,Java 还严格规定了各个基本数据类型的长度。Java 系统本身也具有很强的可移植性,Java 编译器是用 Java 实现的,Java 的运行环境是用 ANSI C 实现的。Java 语言是解释型的:如前所述,Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统中运行。在运行时,Java 平台中的 Java 解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。Java 是高性能的:与那些解释型的高级脚本语言相比,Java 的确是高性能的。事实上,Java 的运行速度随着 JIT(Just-In-Time)编译器技术的发展越来越接近于 C++。Java 语言是多线程的:在 Java 语言中,线程是一种特殊的对象,它必须由 Thread 类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为 Thread(Runnable) 的构造子类将一个实现了 Runnable 接口的对象包装成一个线程,其二,从 Thread 类派生出子类并重写 run 方法,使用该子类创建的对象即为线程。值得注意的是 Thread 类已经实现了 Runnable 接口,因此,任何一个线程均有它的 run 方法,而 run 方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java 语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为 synchronized)。Java 语言是动态的:Java 语言的设计目标之一是适应于动态变化的环境。Java 程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java 中的类有一个运行时刻的表示,能进行运行时刻的类型检查。

5,392

社区成员

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

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