网络通信中的心跳机制的实现
2013-05-01 14:55
387 查看
有开发网络应用经历的人都知道,网络中的接收和发送数据都是使用WINDOWS中的SOCKET进行实现。但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题。可是如何判断这个套接字是否还可以使用呢?
有人一定想到使用Send函数中的返回结果来进行判断。如果返回的长度和自己发送出去的长度一致,那就说明这个套接字是可用的,否则此套接字一定出现了问题。但是我们并不是无时无刻的发送数据呀。如何解决呢?
其实TCP中已经为我们实现了一个叫做心跳的机制。如果你设置了心跳,那TCP就会在一定的时间(比如你设置的是3秒钟)内发送你设置的次数的心跳(比如说2次),并且此信息不会影响你自己定义的协议。
在VC中实现心跳的例子很多,可是在DLEPHI中一直没有相应的代码。下面我是我使用DELPHI编写的关于心跳的代码(以IOCP为例),希望对大家有帮助。
定义心跳常量
const
IOC_IN =$80000000;
IOC_VENDOR
=$18000000;
IOC_out =$40000000;
SIO_KEEPALIVE_VALS =IOC_IN
or IOC_VENDOR or 4;
var
inKeepAlive,OutKeepAlive:TTCP_KEEPALIVE;
实现代码是在Acceptsc:= WSAAccept(Listensc, nil, nil, nil, 0);代码的后面加入:
opt:=1;
if
setsockopt(Acceptsc,SOL_SOCKET,SO_KEEPALIVE,@opt,sizeof(opt))=SOCKET_ERROR
then
begin
closesocket(Acceptsc);
end;
inKeepAlive.onoff:=1;
//设置3秒钟时间间隔
inKeepAlive.keepalivetime:=3000;
//设置每3秒中发送1次的心跳
inKeepAlive.keepaliveinterval:=1;
insize:=sizeof(TTCP_KEEPALIVE);
outsize:=sizeof(TTCP_KEEPALIVE);
if
WSAIoctl(Accept,SIO_KEEPALIVE_VALS,@inKeepAlive,insize,@outKeepAlive,outsize,@outByte,nil,nil)=SOCKET_ERROR
then
begin
closesocket(Acceptsc);
end;
如果加入以上的代码以后,系统会每3秒中加入一次的心跳。并且如果客户端断线以后(网线断),函数GetQueuedCompletionStatus会返回FALSE。
if (GetQueuedCompletionStatus(CompletionPort,
BytesTransferred,DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) =
False) then
begin
//在这里处理客户端断线信息。
continue;
end;
以上就是我使用心跳的方法,此方法我已经在我的网络游戏中使用。情况稳定!
有人一定想到使用Send函数中的返回结果来进行判断。如果返回的长度和自己发送出去的长度一致,那就说明这个套接字是可用的,否则此套接字一定出现了问题。但是我们并不是无时无刻的发送数据呀。如何解决呢?
其实TCP中已经为我们实现了一个叫做心跳的机制。如果你设置了心跳,那TCP就会在一定的时间(比如你设置的是3秒钟)内发送你设置的次数的心跳(比如说2次),并且此信息不会影响你自己定义的协议。
在VC中实现心跳的例子很多,可是在DLEPHI中一直没有相应的代码。下面我是我使用DELPHI编写的关于心跳的代码(以IOCP为例),希望对大家有帮助。
定义心跳常量
const
IOC_IN =$80000000;
IOC_VENDOR
=$18000000;
IOC_out =$40000000;
SIO_KEEPALIVE_VALS =IOC_IN
or IOC_VENDOR or 4;
var
inKeepAlive,OutKeepAlive:TTCP_KEEPALIVE;
实现代码是在Acceptsc:= WSAAccept(Listensc, nil, nil, nil, 0);代码的后面加入:
opt:=1;
if
setsockopt(Acceptsc,SOL_SOCKET,SO_KEEPALIVE,@opt,sizeof(opt))=SOCKET_ERROR
then
begin
closesocket(Acceptsc);
end;
inKeepAlive.onoff:=1;
//设置3秒钟时间间隔
inKeepAlive.keepalivetime:=3000;
//设置每3秒中发送1次的心跳
inKeepAlive.keepaliveinterval:=1;
insize:=sizeof(TTCP_KEEPALIVE);
outsize:=sizeof(TTCP_KEEPALIVE);
if
WSAIoctl(Accept,SIO_KEEPALIVE_VALS,@inKeepAlive,insize,@outKeepAlive,outsize,@outByte,nil,nil)=SOCKET_ERROR
then
begin
closesocket(Acceptsc);
end;
如果加入以上的代码以后,系统会每3秒中加入一次的心跳。并且如果客户端断线以后(网线断),函数GetQueuedCompletionStatus会返回FALSE。
if (GetQueuedCompletionStatus(CompletionPort,
BytesTransferred,DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) =
False) then
begin
//在这里处理客户端断线信息。
continue;
end;
以上就是我使用心跳的方法,此方法我已经在我的网络游戏中使用。情况稳定!
相关文章推荐
- 网络通信中的心跳机制的实现
- 网络通信中的心跳机制的实现!
- 网络通信中的心跳机制的实现
- 网络通信中的心跳机制的实现! 推荐
- [摘录]网络通信中的心跳机制的实现
- 网络通信中的心跳机制的实现!
- 回合制游戏网络通信协议及心跳机制调研
- Java实现——Socket网络通信的机制以及实现举例
- Python网络编程:实现心跳机制
- Network——Socket网络通信机制以及实现举例(TCP、UDP等)
- TCP实现在不同局域网下的两台电脑网络通信(Python实现)
- 使用HttpClient接口实现网络通信
- IOS网络篇7之基于第三方CocoaAsyncSocket实现Socket通信(发送图片以及类似http头信息)
- Android -- Ethernet网络模块中NetworkFactory与NetworkAgent的通信机制
- 网络游戏客户端通信模块简单实现
- boost::asio::ip::tcp实现网络通信的小例子
- android网络通信之-Http(Android操作HTTP实现与服务器通信)
- 基于TCP/IP的SOCKET接口实现网络通信
- 网关,路由,局域网内的通信及不同的网络间通信实现的原理剖析