
一、什么是Keep-Alive模式?
我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成 之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服 务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。
http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive",才能启用Keep-Alive;http 1.1中默认启用Keep-Alive,如果加入"Connection: close ",才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep- Alive连接就看服务器设置情况。
二、代码使用
SetKeepAliveValues 方法启用或禁用 TCP 保持选项指定的 TCP 保持超时和间隔用于保持 TCP 数据包的每个连接设置。保持选项的详细信息,请参阅 4.2.3.6 节要求的互联网 HostsCommunication 图层在 IETF 网站上可用的 RFC 1122 中指定。
optionInValue 参数,传递给 Socket.IOControl 应指向 Mstcpip.h 头文件中定义的 tcp_keepalive 结构。这种结构的定义如下:
/* Argument structure for SIO_KEEPALIVE_VALS */
struct tcp_keepalive {
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};
将 tcp_keepalive C 转换为 C# struct结构
// Convert tcp_keepalive C struct To C# struct
[
System.Runtime.InteropServices.StructLayout
(
System.Runtime.InteropServices.LayoutKind.Explicit
)
]
unsafe struct TcpKeepAlive
{
[System.Runtime.InteropServices.FieldOffset()]
[
System.Runtime.InteropServices.MarshalAs
(
System.Runtime.InteropServices.UnmanagedType.ByValArray,
SizeConst =
)
]
public fixed byte Bytes[]; [System.Runtime.InteropServices.FieldOffset()]
public uint On_Off; [System.Runtime.InteropServices.FieldOffset()]
public uint KeepaLiveTime; [System.Runtime.InteropServices.FieldOffset()]
public uint KeepaLiveInterval;
} public int SetKeepAliveValues
(
System.Net.Sockets.Socket Socket,
bool On_Off,
uint KeepaLiveTime,
uint KeepaLiveInterval
)
{
int Result = -; unsafe
{
TcpKeepAlive KeepAliveValues = new TcpKeepAlive(); KeepAliveValues.On_Off = Convert.ToUInt32(On_Off);
KeepAliveValues.KeepaLiveTime = KeepaLiveTime;
KeepAliveValues.KeepaLiveInterval = KeepaLiveInterval; byte[] InValue = new byte[]; for (int I = ; I < ; I++)
InValue[I] = KeepAliveValues.Bytes[I]; Result = Socket.IOControl(IOControlCode.KeepAliveValues, InValue, null);
} return Result;
}
调用方法:
System.Net.Sockets.Socket Socket = new System.Net.Sockets.Socket
(
System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp
); // Set 10 Hours: 10 * 60 * 60 * 1000 = 36,000,000 every 1 Second 1000
SetKeepAliveValues(Socket, true, , );