|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Using TCP/IP KeepAlive in C#I have tried the following code public virtual void SetKeepAlive (ulong keepalive_time, ulong keepalive_interval) { int bytes_per_long = 32 / 8; byte [] keep_alive = new byte[3*bytes_per_long]; ulong [] input_params = new ulong[3]; int i1; int bits_per_byte = 8; if (keepalive_time == 0 || keepalive_interval == 0) input_params[0] = 0; else input_params[0] = 1; input_params[1] = keepalive_time; input_params[2] = keepalive_interval; for (i1=0; i1<input_params.Length; i1++) { keep_alive[i1*bytes_per_long+3] = (byte)(input_params[i1] >> ((bytes_per_long - 1) * bits_per_byte) & 0xff); keep_alive[i1*bytes_per_long+2] = (byte)(input_params[i1] >> ((bytes_per_long - 2) * bits_per_byte) & 0xff); keep_alive[i1*bytes_per_long+1] = (byte)(input_params[i1] >> ((bytes_per_long - 3) * bits_per_byte) & 0xff); keep_alive[i1*bytes_per_long+0] = (byte)(input_params[i1] >> ((bytes_per_long - 4) * bits_per_byte) & 0xff); } LogTrace.Trace(this,"Keep Alive Bits: {0}",ByteArrayFormater.HexDump(keep_alive)); NetSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.KeepAlive,keep_alive); } /* method AsyncSocket SetKeepAlive */ The result is not error, no exception and no keepalive in the expected time frame. I am passing both times in mill-seconds. The Trace that I have shows 12 bytes in the form of 01 00 00 00 10 27 00 00 98 3a 00 00 when called as SetKeepAlive(10000,15000); I am not really sure if I need to put the bytes in this order or not. If working directly with the Winsock API, the keepalive option uses a structure of 3 ULONGS with a 1 in the first one, the time in the 2nd one and the retry time (interval in this code) in the third one. Any help on this would be appreciated. ------------------------------------------- Roy Chastain KMSYS Worldwide, Inc. http://www.kmsys.com Roy Chastain wrote:
Show quote > I have been trying to make NetSocket.SetSocketOption work for TCP/IP KeepAlive I'm not sure that .NET implementation expects timeouts. I think it > > I have tried the following code > > public virtual void SetKeepAlive (ulong keepalive_time, ulong keepalive_interval) > { > int bytes_per_long = 32 / 8; > byte [] keep_alive = new byte[3*bytes_per_long]; .... > LogTrace.Trace(this,"Keep Alive Bits: {0}",ByteArrayFormater.HexDump(keep_alive)); > NetSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.keep alive,keep_alive); > } /* method AsyncSocket SetKeepAlive */ > > > The result is not error, no exception and no keepalive in the expected time frame. > I am passing both times in mill-seconds. The Trace that I have shows 12 bytes in the form of > 01 00 00 00 10 27 00 00 98 3a 00 00 when called as SetKeepAlive(10000,15000); .... expects bool (enable/disable). Maybe you cold PInvoke WSAIoctl... Regards, Goran I have done this in the past
socket.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.KeepAlive,1); and then I tweaked the registry entries to set keep-alive intervals The reg keys are located at [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters] KeepAliveTime = milliseconds Specifies the connection idle time in milliseconds before TCP will begin sending keepalives, if keepalives are enabled on a connection. The default is 2 hours (7,200,000). KeepAliveInterval = 32-bit number Specifies the time in milliseconds between retransmissions of keepalives, once the KeepAliveTime has expired. Once KeepAliveTime has expired, keepalives are sent every KeepAliveInterval milliseconds until a response is received, up to a maximum of MaxDataRetries before the connection is terminated. The default is 1 second (1000). Roy Chastain wrote: Show quote > I have been trying to make NetSocket.SetSocketOption work for TCP/IP KeepAlive > > I have tried the following code > > public virtual void SetKeepAlive (ulong keepalive_time, ulong keepalive_interval) > { > int bytes_per_long = 32 / 8; > byte [] keep_alive = new byte[3*bytes_per_long]; > ulong [] input_params = new ulong[3]; > int i1; > int bits_per_byte = 8; > > if (keepalive_time == 0 || keepalive_interval == 0) > input_params[0] = 0; > else > input_params[0] = 1; > input_params[1] = keepalive_time; > input_params[2] = keepalive_interval; > for (i1=0; i1<input_params.Length; i1++) > { > keep_alive[i1*bytes_per_long+3] = (byte)(input_params[i1] >> ((bytes_per_long - 1) * bits_per_byte) & 0xff); > keep_alive[i1*bytes_per_long+2] = (byte)(input_params[i1] >> ((bytes_per_long - 2) * bits_per_byte) & 0xff); > keep_alive[i1*bytes_per_long+1] = (byte)(input_params[i1] >> ((bytes_per_long - 3) * bits_per_byte) & 0xff); > keep_alive[i1*bytes_per_long+0] = (byte)(input_params[i1] >> ((bytes_per_long - 4) * bits_per_byte) & 0xff); > } > LogTrace.Trace(this,"Keep Alive Bits: {0}",ByteArrayFormater.HexDump(keep_alive)); > NetSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.KeepAlive,keep_alive); > } /* method AsyncSocket SetKeepAlive */ > > > The result is not error, no exception and no keepalive in the expected time frame. > I am passing both times in mill-seconds. The Trace that I have shows 12 bytes in the form of > 01 00 00 00 10 27 00 00 98 3a 00 00 when called as SetKeepAlive(10000,15000); > > I am not really sure if I need to put the bytes in this order or not. If working directly with the Winsock API, the keepalive > option uses a structure of 3 ULONGS with a 1 in the first one, the time in the 2nd one and the retry time (interval in this code) > in the third one. > > Any help on this would be appreciated. > ------------------------------------------- > Roy Chastain > KMSYS Worldwide, Inc. > http://www.kmsys.com Thanks for you comments. Your solution explains the note in the doc that says that KeepAlives can be enabled with the form of the
function that uses the int as the 3rd parameter. I might go that way for a bit, but in the long run I want more control than the registry offers. (I want different sockets to have different values.) On 3 Aug 2006 09:22:50 -0700, appz***@gmail.com wrote: Show quote >I have done this in the past KMSYS Worldwide, Inc.> >socket.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.KeepAlive,1); > >and then I tweaked the registry entries to set keep-alive intervals >The reg keys are located at >[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters] > >KeepAliveTime = milliseconds >Specifies the connection idle time in milliseconds before TCP will >begin sending keepalives, if keepalives are enabled on a connection. >The default is 2 hours (7,200,000). > >KeepAliveInterval = 32-bit number >Specifies the time in milliseconds between retransmissions of >keepalives, once the KeepAliveTime has expired. Once KeepAliveTime has >expired, keepalives are sent every KeepAliveInterval milliseconds until >a response is received, up to a maximum of MaxDataRetries before the >connection is terminated. The default is 1 second (1000). > > >Roy Chastain wrote: >> I have been trying to make NetSocket.SetSocketOption work for TCP/IP KeepAlive >> >> I have tried the following code >> >> public virtual void SetKeepAlive (ulong keepalive_time, ulong keepalive_interval) >> { >> int bytes_per_long = 32 / 8; >> byte [] keep_alive = new byte[3*bytes_per_long]; >> ulong [] input_params = new ulong[3]; >> int i1; >> int bits_per_byte = 8; >> >> if (keepalive_time == 0 || keepalive_interval == 0) >> input_params[0] = 0; >> else >> input_params[0] = 1; >> input_params[1] = keepalive_time; >> input_params[2] = keepalive_interval; >> for (i1=0; i1<input_params.Length; i1++) >> { >> keep_alive[i1*bytes_per_long+3] = (byte)(input_params[i1] >> ((bytes_per_long - 1) * bits_per_byte) & 0xff); >> keep_alive[i1*bytes_per_long+2] = (byte)(input_params[i1] >> ((bytes_per_long - 2) * bits_per_byte) & 0xff); >> keep_alive[i1*bytes_per_long+1] = (byte)(input_params[i1] >> ((bytes_per_long - 3) * bits_per_byte) & 0xff); >> keep_alive[i1*bytes_per_long+0] = (byte)(input_params[i1] >> ((bytes_per_long - 4) * bits_per_byte) & 0xff); >> } >> LogTrace.Trace(this,"Keep Alive Bits: {0}",ByteArrayFormater.HexDump(keep_alive)); >> NetSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.KeepAlive,keep_alive); >> } /* method AsyncSocket SetKeepAlive */ >> >> >> The result is not error, no exception and no keepalive in the expected time frame. >> I am passing both times in mill-seconds. The Trace that I have shows 12 bytes in the form of >> 01 00 00 00 10 27 00 00 98 3a 00 00 when called as SetKeepAlive(10000,15000); >> >> I am not really sure if I need to put the bytes in this order or not. If working directly with the Winsock API, the keepalive >> option uses a structure of 3 ULONGS with a 1 in the first one, the time in the 2nd one and the retry time (interval in this code) >> in the third one. >> >> Any help on this would be appreciated. >> ------------------------------------------- >> Roy Chastain >> KMSYS Worldwide, Inc. >> http://www.kmsys.com ------------------------------------------- Roy Chastain http://www.kmsys.com Hi Roy,
In Windows 2000 and later Windows operating systems, we can control the per-connection setting of keep-alive option, keepalive time, and keepalive interval. Basically, this could be done by the PSDK API WSAIoctl(...) with the SIO_KEEPALIVE_VALS as its IOControlCode: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/win sock/wsaioctl_2.asp The .NET framework also provides a method to access that low level functionality: Socket.IOControl. I found a newsgroup thread which discuss the usage on using the SIO_KEEPALIVE_VALS: Socket.IOControl and SIO_KEEPALIVE_VALS http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/brow se_thread/thread/a71b3a2912595769/48c72a728cc51a57?lnk=st&q=&rnum=1&hl=en#48 c72a728cc51a57 Socket.IOControl Method (IOControlCode, Byte[], Byte[]) http://msdn2.microsoft.com/en-us/library/8a3744sh.aspx I hope the above information helps, if you have any issues or concerns please let me know. I will be happy to be of further assistance. Thanks! Best regards, Gary Chang Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Okay, the message thread you pointed me is a discussion of Socket.IOControl that gets fairly messy in the 1.1 environment. I am
in the 1.1 environment.. My attempt uses Socket.SetSocketOption and eventually these 2 methods should end up running through the same code in WinSock. I know how to set a KeepAlive in C++ using WinSock. I have been doing that for years. The question that still remains using IOControl is, "What is the proper packing of the ULONGS into the byte array?" Given the SIO_KEEPALIVE_VALS structure of struct tcp_keepalive { u_long onoff; u_long keepalivetime; u_long keepaliveinterval; }; onoff will be 1 keepalivetime will be 10000 keepaliveinterval will be 15000 Should the byte array be packed like this 01 00 00 00 10 27 00 00 98 3a 00 00 or should they be packed like this 00 00 00 01 00 00 27 10 00 00 3a 98 or possibly some other pattern I have not figured out? AND is this pattern machine dependent. (Intel vs. rest of the world?) Also as an aside, do we expect SetSocketOption to work once the bytes are in the correct order or do I have to change to IOControl? If we do not expect tSetSocketOption to work, then KeepAlive should be removed from the SocketOptionName enumeration. On Thu, 10 Aug 2006 09:55:17 GMT, v-gar***@online.microsoft.com ("Gary Chang[MSFT]") wrote: Show quote >Hi Roy, KMSYS Worldwide, Inc.> >In Windows 2000 and later Windows operating systems, we can control the >per-connection setting of keep-alive option, keepalive time, and keepalive >interval. Basically, this could be done by the PSDK API WSAIoctl(...) with >the SIO_KEEPALIVE_VALS as its IOControlCode: > >http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/win >sock/wsaioctl_2.asp > > >The .NET framework also provides a method to access that low level >functionality: Socket.IOControl. I found a newsgroup thread which discuss >the usage on using the SIO_KEEPALIVE_VALS: > >Socket.IOControl and SIO_KEEPALIVE_VALS >http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/brow >se_thread/thread/a71b3a2912595769/48c72a728cc51a57?lnk=st&q=&rnum=1&hl=en#48 >c72a728cc51a57 > >Socket.IOControl Method (IOControlCode, Byte[], Byte[]) >http://msdn2.microsoft.com/en-us/library/8a3744sh.aspx > > >I hope the above information helps, if you have any issues or concerns >please let me know. I will be happy to be of further assistance. > >Thanks! > >Best regards, > >Gary Chang >Microsoft Online Community Support >================================================== >Get notification to my posts through email? Please refer to >http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif >ications. >================================================== >This posting is provided "AS IS" with no warranties, and confers no rights. ------------------------------------------- Roy Chastain http://www.kmsys.com Hi Roy,
>Okay, the message thread you pointed me is a discussion Just as that thread discussed, you can define the enum code manually:>of Socket.IOControl that gets fairly messy in the 1.1 >environment. I am in the 1.1 environment.. SIO_KEEPALIVE_VALS is: -1744830460 (or 0x98000004) >Should the byte array be packed like this The above is exactly the raw byte array layout of the struct tcp_keepalive >01 00 00 00 10 27 00 00 98 3a 00 00 in little endian machine, you can take this one in most Windows platforms. But it would be better to write some little code to test the machine's endian type, then transfer the proper byte array due to the machine's endian type. >Also as an aside, do we expect SetSocketOption to work once The .NET framework's SetSocketOption method hasn't provided much control to >the bytes are in the correct order or do I have to change to >IOControl? low level socket settings. Its socket option for the keep alive feature could only be zero or non-zero value, it is used to enable or disable the KeepAlive feature. So pass a byte array would not work. I suggest you take the IOControl approach. Thanks for your understanding. Best regards, Gary Chang Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||