History

GSF.Communication: Added try-catch to AddMulticastMembership and DropMulticastMembership in UdpClient.cs to avoid errors when calling SetSocketOption. GSF.PhasorProtocols: In MultiProtocolFrameParser, added user-unhandled exception handlers for the command channel and the data channel.

StephenCWills committed 13 years ago

Commit 635b5301 parent 84014222 files · +104 −48Browse files

Unified · Split

2 files
  1. Source/Libraries/GSF.Communication/UdpClient.cs +65 −48
  2. Source/Libraries/GSF.PhasorProtocols/MultiProtocolFrameParser.cs +39 −0
Source/Libraries/GSF.Communication/UdpClient.cs+65−48
@@ -1250,55 +1250,19 @@ namespace GSF.Communication · 1249 unmodified lines
12501250
12511251 private void AddMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, out byte[] multicastMembershipAddresses)
12521252 {
1253− if (!Transport.IsMulticastIP(serverAddress))
1254− throw new InvalidOperationException("Cannot add multicast membership if server address is not a multicast IP.");
1253+ multicastMembershipAddresses = null;
12551254
1256− if ((object)sourceAddress == null)
1257− {
1258− // Execute multicast subscribe for any source
1259− m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(serverAddress));
1260− multicastMembershipAddresses = null;
1261− }
1262− else
1255+ try
12631256 {
1264− IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address;
1265−
1266− if (sourceAddress.AddressFamily != serverAddress.AddressFamily)
1267− throw new InvalidOperationException(string.Format("Source address \"{0}\" is not in the same IP format as server address \"{1}\"", sourceAddress, serverAddress));
1268−
1269− if (localAddress.AddressFamily != serverAddress.AddressFamily)
1270− throw new InvalidOperationException(string.Format("Local address \"{0}\" is not in the same IP format as server address \"{1}\"", localAddress, serverAddress));
1271−
1272− MemoryStream membershipAddresses = new MemoryStream();
1273−
1274− byte[] serverAddressBytes = serverAddress.GetAddressBytes();
1275− byte[] sourceAddressBytes = sourceAddress.GetAddressBytes();
1276− byte[] localAddressBytes = localAddress.GetAddressBytes();
1277−
1278− membershipAddresses.Write(serverAddressBytes, 0, serverAddressBytes.Length);
1279− membershipAddresses.Write(sourceAddressBytes, 0, sourceAddressBytes.Length);
1280− membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length);
1281−
1282− multicastMembershipAddresses = membershipAddresses.ToArray();
1283−
1284− // Execute multicast subscribe for specific source
1285− m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, multicastMembershipAddresses);
1286− }
1287− }
1257+ if (!Transport.IsMulticastIP(serverAddress))
1258+ throw new InvalidOperationException("Cannot add multicast membership if server address is not a multicast IP.");
12881259
1289− private void DropMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, byte[] multicastMembershipAddresses)
1290− {
1291− if (!Transport.IsMulticastIP(serverAddress))
1292− throw new InvalidOperationException("Cannot drop multicast membership if server address is not a multicast IP.");
1293−
1294− if ((object)sourceAddress == null && (object)multicastMembershipAddresses == null)
1295− {
1296− // Execute multicast unsubscribe for any source
1297− m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropMembership, new MulticastOption(serverAddress));
1298− }
1299− else
1300− {
1301− if ((object)multicastMembershipAddresses == null)
1260+ if ((object)sourceAddress == null)
1261+ {
1262+ // Execute multicast subscribe for any source
1263+ m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(serverAddress));
1264+ }
1265+ else
13021266 {
13031267 IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address;
13041268
@@ -1309,6 +1273,7 @@ namespace GSF.Communication · 4 unmodified lines
13091273 throw new InvalidOperationException(string.Format("Local address \"{0}\" is not in the same IP format as server address \"{1}\"", localAddress, serverAddress));
13101274
13111275 MemoryStream membershipAddresses = new MemoryStream();
1276+
13121277 byte[] serverAddressBytes = serverAddress.GetAddressBytes();
13131278 byte[] sourceAddressBytes = sourceAddress.GetAddressBytes();
13141279 byte[] localAddressBytes = localAddress.GetAddressBytes();
@@ -1318,10 +1283,62 @@ namespace GSF.Communication · 3 unmodified lines
13181283 membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length);
13191284
13201285 multicastMembershipAddresses = membershipAddresses.ToArray();
1286+
1287+ // Execute multicast subscribe for specific source
1288+ m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, multicastMembershipAddresses);
13211289 }
1290+ }
1291+ catch (SocketException ex)
1292+ {
1293+ if (ex.SocketErrorCode != SocketError.InvalidArgument)
1294+ throw;
1295+ }
1296+ }
13221297
1323− // Execute multicast unsubscribe for specific source
1324− m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropSourceMembership, multicastMembershipAddresses);
1298+ private void DropMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, byte[] multicastMembershipAddresses)
1299+ {
1300+ try
1301+ {
1302+ if (!Transport.IsMulticastIP(serverAddress))
1303+ throw new InvalidOperationException("Cannot drop multicast membership if server address is not a multicast IP.");
1304+
1305+ if ((object)sourceAddress == null && (object)multicastMembershipAddresses == null)
1306+ {
1307+ // Execute multicast unsubscribe for any source
1308+ m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropMembership, new MulticastOption(serverAddress));
1309+ }
1310+ else
1311+ {
1312+ if ((object)multicastMembershipAddresses == null)
1313+ {
1314+ IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address;
1315+
1316+ if (sourceAddress.AddressFamily != serverAddress.AddressFamily)
1317+ throw new InvalidOperationException(string.Format("Source address \"{0}\" is not in the same IP format as server address \"{1}\"", sourceAddress, serverAddress));
1318+
1319+ if (localAddress.AddressFamily != serverAddress.AddressFamily)
1320+ throw new InvalidOperationException(string.Format("Local address \"{0}\" is not in the same IP format as server address \"{1}\"", localAddress, serverAddress));
1321+
1322+ MemoryStream membershipAddresses = new MemoryStream();
1323+ byte[] serverAddressBytes = serverAddress.GetAddressBytes();
1324+ byte[] sourceAddressBytes = sourceAddress.GetAddressBytes();
1325+ byte[] localAddressBytes = localAddress.GetAddressBytes();
1326+
1327+ membershipAddresses.Write(serverAddressBytes, 0, serverAddressBytes.Length);
1328+ membershipAddresses.Write(sourceAddressBytes, 0, sourceAddressBytes.Length);
1329+ membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length);
1330+
1331+ multicastMembershipAddresses = membershipAddresses.ToArray();
1332+ }
1333+
1334+ // Execute multicast unsubscribe for specific source
1335+ m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropSourceMembership, multicastMembershipAddresses);
1336+ }
1337+ }
1338+ catch (SocketException ex)
1339+ {
1340+ if (ex.SocketErrorCode != SocketError.InvalidArgument)
1341+ throw;
13251342 }
13261343 }
13271344
Source/Libraries/GSF.PhasorProtocols/MultiProtocolFrameParser.cs+39−0
@@ -937,6 +937,7 @@ namespace GSF.PhasorProtocols · 936 unmodified lines
937937 sharedClient.ReceiveDataException += SharedClient_ReceiveDataException;
938938 sharedClient.ReceiveDataFrom += SharedClient_ReceiveDataFrom;
939939 sharedClient.SendDataException += SharedClient_SendDataException;
940+ sharedClient.UnhandledUserException += SharedClient_UnhandledUserException;
940941
941942 if (!sharing)
942943 {
@@ -1139,6 +1140,14 @@ namespace GSF.PhasorProtocols · 196 unmodified lines
11391140 SendDataException(this, e);
11401141 }
11411142
1143+ // Shared client unhandled user exception handler.
1144+ // Forwards event to users attached to this client.
1145+ private void SharedClient_UnhandledUserException(object sender, EventArgs<Exception> e)
1146+ {
1147+ if ((object)UnhandledUserException != null)
1148+ UnhandledUserException(this, e);
1149+ }
1150+
11421151 #endregion
11431152
11441153 #region [ Static ]
@@ -2527,6 +2536,7 @@ namespace GSF.PhasorProtocols · 1382 unmodified lines
25272536 m_commandChannel.ReceiveData += m_commandChannel_ReceiveData;
25282537 m_commandChannel.ReceiveDataException += m_commandChannel_ReceiveDataException;
25292538 m_commandChannel.SendDataException += m_commandChannel_SendDataException;
2539+ m_commandChannel.UnhandledUserException += m_commandChannel_UnhandledUserException;
25302540
25312541 // Attempt connection to device over command channel
25322542 m_commandChannel.ReceiveBufferSize = m_bufferSize;
@@ -2595,6 +2605,7 @@ namespace GSF.PhasorProtocols · 62 unmodified lines
25952605 m_dataChannel.ReceiveData += m_dataChannel_ReceiveData;
25962606 m_dataChannel.ReceiveDataException += m_dataChannel_ReceiveDataException;
25972607 m_dataChannel.SendDataException += m_dataChannel_SendDataException;
2608+ m_dataChannel.UnhandledUserException += m_dataChannel_UnhandledUserException;
25982609
25992610 // Attempt connection to device
26002611 m_dataChannel.ReceiveBufferSize = m_bufferSize;
@@ -2612,6 +2623,7 @@ namespace GSF.PhasorProtocols · 11 unmodified lines
26122623 m_serverBasedDataChannel.ReceiveClientData += m_serverBasedDataChannel_ReceiveClientData;
26132624 m_serverBasedDataChannel.ReceiveClientDataException += m_serverBasedDataChannel_ReceiveClientDataException;
26142625 m_serverBasedDataChannel.SendClientDataException += m_serverBasedDataChannel_SendClientDataException;
2626+ m_serverBasedDataChannel.UnhandledUserException += m_serverBasedDataChannel_UnhandledUserException;
26152627
26162628 // Listen for device connection
26172629 m_serverBasedDataChannel.ReceiveBufferSize = m_bufferSize;
@@ -2702,6 +2714,7 @@ namespace GSF.PhasorProtocols · 84 unmodified lines
27022714 m_dataChannel.ReceiveData -= m_dataChannel_ReceiveData;
27032715 m_dataChannel.ReceiveDataException -= m_dataChannel_ReceiveDataException;
27042716 m_dataChannel.SendDataException -= m_dataChannel_SendDataException;
2717+ m_dataChannel.UnhandledUserException -= m_dataChannel_UnhandledUserException;
27052718 m_dataChannel.Dispose();
27062719 }
27072720 }
@@ -2726,6 +2739,7 @@ namespace GSF.PhasorProtocols · 18 unmodified lines
27262739 m_serverBasedDataChannel.ReceiveClientData -= m_serverBasedDataChannel_ReceiveClientData;
27272740 m_serverBasedDataChannel.ReceiveClientDataException -= m_serverBasedDataChannel_ReceiveClientDataException;
27282741 m_serverBasedDataChannel.SendClientDataException -= m_serverBasedDataChannel_SendClientDataException;
2742+ m_serverBasedDataChannel.UnhandledUserException -= m_serverBasedDataChannel_UnhandledUserException;
27292743 m_serverBasedDataChannel.Dispose();
27302744 }
27312745 }
@@ -2750,6 +2764,7 @@ namespace GSF.PhasorProtocols · 18 unmodified lines
27502764 m_commandChannel.ReceiveData -= m_commandChannel_ReceiveData;
27512765 m_commandChannel.ReceiveDataException -= m_commandChannel_ReceiveDataException;
27522766 m_commandChannel.SendDataException -= m_commandChannel_SendDataException;
2767+ m_commandChannel.UnhandledUserException -= m_commandChannel_UnhandledUserException;
27532768 m_commandChannel.Dispose();
27542769 }
27552770 }
@@ -3415,6 +3430,14 @@ namespace GSF.PhasorProtocols · 659 unmodified lines
34153430 OnParsingException(e.Argument, "Data channel receive exception: {0}", ex.Message);
34163431 }
34173432
3433+ private void m_dataChannel_UnhandledUserException(object sender, EventArgs<Exception> e)
3434+ {
3435+ Exception ex = e.Argument;
3436+
3437+ if (!(ex is NullReferenceException) && !(ex is ObjectDisposedException))
3438+ OnParsingException(e.Argument, "Data channel user unhandled exception: {0}", ex.Message);
3439+ }
3440+
34183441 #endregion
34193442
34203443 #region [ Server Based Data Channel Event Handlers ]
@@ -3477,6 +3500,14 @@ namespace GSF.PhasorProtocols · 56 unmodified lines
34773500 OnParsingException(e.Argument2, "Server based data channel receive exception: {0}", ex.Message);
34783501 }
34793502
3503+ private void m_serverBasedDataChannel_UnhandledUserException(object sender, EventArgs<Exception> e)
3504+ {
3505+ Exception ex = e.Argument;
3506+
3507+ if (!(ex is NullReferenceException) && !(ex is ObjectDisposedException))
3508+ OnParsingException(e.Argument, "Server based data channel user unhandled exception: {0}", ex.Message);
3509+ }
3510+
34803511 #endregion
34813512
34823513 #region [ Command Channel Event Handlers ]
@@ -3553,6 +3584,14 @@ namespace GSF.PhasorProtocols · 70 unmodified lines
35533584 OnParsingException(e.Argument, "Command channel send exception: {0}", ex.Message);
35543585 }
35553586
3587+ private void m_commandChannel_UnhandledUserException(object sender, EventArgs<Exception> e)
3588+ {
3589+ Exception ex = e.Argument;
3590+
3591+ if (!(ex is NullReferenceException) && !(ex is ObjectDisposedException))
3592+ OnParsingException(e.Argument, "Command channel user unhandled exception: {0}", ex.Message);
3593+ }
3594+
35563595 #endregion
35573596
35583597 #region [ Frame Parser Event Handlers ]

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t