4
4
using System . Collections . Generic ;
5
5
using System . Linq ;
6
6
using System . Net ;
7
+ using System . Net . NetworkInformation ;
7
8
using System . Net . Sockets ;
8
9
using System . Threading ;
9
10
@@ -26,40 +27,70 @@ public class CanOverEthernet : ICanTrafficInterface
26
27
27
28
private Thread UdpReceiverThread ;
28
29
private UdpClient udpReceiverConnection ;
29
- private UdpClient udpSenderConnection ;
30
- private Boolean isConnected ;
30
+ private List < UdpClient > udpSenderConnections ;
31
+ private Boolean isConnected = false ;
31
32
private IPAddress ipAddressMulticast ;
32
33
private IPEndPoint ipEndPointMulticast ;
33
34
private IPEndPoint localEndPoint ;
34
35
35
- public string Ip ;
36
- public int Port ;
36
+ public string Ip { get ; set ; } = DEFAULT_IPADDRESS ;
37
+ public int Port { get ; set ; } = DEFAULT_PORT ;
37
38
public ReceivedCanPacketHandler ReceivedCanPacketCallBack { get ; set ; }
39
+ public List < string > SelectedInterfaces { get ; set ; }
38
40
39
- public CanOverEthernet ( string Ip , int Port , ReceivedCanPacketHandler receivedCanPacketCallBack )
41
+ internal void Close ( )
40
42
{
41
- this . Ip = Ip ;
42
- this . Port = Port ;
43
- this . ReceivedCanPacketCallBack = receivedCanPacketCallBack ;
44
-
45
- if ( Ip == null || Ip . Length == 0 || Port == 0 ) return ;
46
-
47
- this . isConnected = false ;
43
+ Disconnect ( ) ;
48
44
}
49
45
50
- public CanOverEthernet ( ReceivedCanPacketHandler receivedCanPacketHandler )
46
+ public Dictionary < string , string > AvailableInterfaces
51
47
{
52
- this . Ip = DEFAULT_IPADDRESS ;
53
- this . Port = DEFAULT_PORT ;
54
- this . ReceivedCanPacketCallBack = receivedCanPacketHandler ;
55
- this . isConnected = false ;
56
- }
48
+ get
49
+ {
50
+ Dictionary < string , string > availableInterfaces = null ;
57
51
58
- internal void Close ( )
59
- {
60
- Disconnect ( ) ;
52
+ // Find all available network interfaces
53
+ NetworkInterface [ ] networkInterfaces = NetworkInterface . GetAllNetworkInterfaces ( ) ;
54
+
55
+ foreach ( NetworkInterface networkInterface in networkInterfaces )
56
+ {
57
+ if ( ( ! networkInterface . Supports ( NetworkInterfaceComponent . IPv4 ) ) ||
58
+ ( networkInterface . OperationalStatus != OperationalStatus . Up ) )
59
+ {
60
+ continue ;
61
+ }
62
+
63
+ IPInterfaceProperties adapterProperties = networkInterface . GetIPProperties ( ) ;
64
+ UnicastIPAddressInformationCollection unicastIPAddresses = adapterProperties . UnicastAddresses ;
65
+ IPAddress ipAddress = null ;
66
+
67
+ foreach ( UnicastIPAddressInformation unicastIPAddress in unicastIPAddresses )
68
+ {
69
+ if ( unicastIPAddress . Address . AddressFamily != AddressFamily . InterNetwork )
70
+ {
71
+ continue ;
72
+ }
73
+
74
+ ipAddress = unicastIPAddress . Address ;
75
+ break ;
76
+ }
77
+
78
+ if ( ipAddress == null )
79
+ {
80
+ continue ;
81
+ }
82
+
83
+ if ( availableInterfaces == null )
84
+ availableInterfaces = new Dictionary < string , string > ( ) ;
85
+
86
+ availableInterfaces . Add ( ipAddress . ToString ( ) , ipAddress . ToString ( ) + " - " + networkInterface . Name ) ;
87
+
88
+ }
89
+ return availableInterfaces ;
90
+ }
61
91
}
62
92
93
+
63
94
public Boolean Connect ( )
64
95
{
65
96
@@ -68,25 +99,66 @@ public Boolean Connect()
68
99
ipEndPointMulticast = new IPEndPoint ( this . ipAddressMulticast , this . Port ) ;
69
100
localEndPoint = new IPEndPoint ( IPAddress . Any , this . Port ) ;
70
101
71
- // Setup sender and receiver
72
102
try
73
103
{
74
- udpSenderConnection = new UdpClient ( )
75
- {
76
- ExclusiveAddressUse = false
77
- } ;
78
- udpSenderConnection . Client . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . ReuseAddress , true ) ;
79
- udpSenderConnection . Client . Bind ( localEndPoint ) ;
80
- udpSenderConnection . JoinMulticastGroup ( ipAddressMulticast ) ;
81
- udpSenderConnection . Client . MulticastLoopback = true ;
82
-
83
104
this . udpReceiverConnection = new UdpClient ( )
84
105
{
85
106
ExclusiveAddressUse = false
86
107
} ;
87
108
udpReceiverConnection . Client . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . ReuseAddress , true ) ;
88
109
udpReceiverConnection . Client . Bind ( localEndPoint ) ;
89
- udpReceiverConnection . JoinMulticastGroup ( ipAddressMulticast , 50 ) ;
110
+
111
+ // join multicast group on all available network interfaces
112
+ NetworkInterface [ ] networkInterfaces = NetworkInterface . GetAllNetworkInterfaces ( ) ;
113
+
114
+ foreach ( NetworkInterface networkInterface in networkInterfaces )
115
+ {
116
+ if ( ( ! networkInterface . Supports ( NetworkInterfaceComponent . IPv4 ) ) ||
117
+ ( networkInterface . OperationalStatus != OperationalStatus . Up ) )
118
+ {
119
+ continue ;
120
+ }
121
+
122
+ IPInterfaceProperties adapterProperties = networkInterface . GetIPProperties ( ) ;
123
+ UnicastIPAddressInformationCollection unicastIPAddresses = adapterProperties . UnicastAddresses ;
124
+ IPAddress ipAddress = null ;
125
+
126
+ foreach ( UnicastIPAddressInformation unicastIPAddress in unicastIPAddresses )
127
+ {
128
+ if ( unicastIPAddress . Address . AddressFamily != AddressFamily . InterNetwork )
129
+ {
130
+ continue ;
131
+ }
132
+
133
+ ipAddress = unicastIPAddress . Address ;
134
+ break ;
135
+ }
136
+
137
+ if ( ipAddress == null )
138
+ {
139
+ continue ;
140
+ }
141
+
142
+ if ( SelectedInterfaces != null && ! SelectedInterfaces . Contains ( ipAddress . ToString ( ) ) )
143
+ {
144
+ continue ;
145
+ }
146
+
147
+ udpReceiverConnection . JoinMulticastGroup ( ipAddressMulticast , ipAddress ) ;
148
+
149
+ // Also create a client for this interface and add it to the list of interfaces
150
+ IPEndPoint interfaceEndPoint = new IPEndPoint ( ipAddress , this . Port ) ;
151
+
152
+ UdpClient sendClient = new UdpClient ( ) ;
153
+ sendClient . Client . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . ReuseAddress , true ) ;
154
+ sendClient . Client . MulticastLoopback = true ;
155
+ sendClient . Client . Bind ( interfaceEndPoint ) ;
156
+ sendClient . JoinMulticastGroup ( ipAddressMulticast ) ;
157
+
158
+ if ( udpSenderConnections == null ) udpSenderConnections = new List < UdpClient > ( ) ;
159
+ udpSenderConnections . Add ( sendClient ) ;
160
+ }
161
+
90
162
}
91
163
catch
92
164
{
@@ -104,8 +176,14 @@ public Boolean Disconnect()
104
176
{
105
177
if ( ! isConnected ) return false ;
106
178
107
- udpReceiverConnection . Close ( ) ;
108
- udpSenderConnection . Close ( ) ;
179
+ try
180
+ {
181
+ udpReceiverConnection . Close ( ) ;
182
+ foreach ( UdpClient client in udpSenderConnections )
183
+ client . Close ( ) ;
184
+ }
185
+ catch { }
186
+
109
187
StopReceiver ( ) ;
110
188
111
189
isConnected = false ;
@@ -118,7 +196,17 @@ public int SendMessage(CanPacket canPacket)
118
196
if ( ! isConnected ) return - 1 ;
119
197
120
198
var data = canPacket . RawBytes ;
121
- return udpSenderConnection . Send ( data , data . Length , ipEndPointMulticast ) ;
199
+
200
+ int resultToReturn = 0 ;
201
+
202
+ foreach ( UdpClient client in udpSenderConnections )
203
+ {
204
+ int result = client . Send ( data , data . Length , ipEndPointMulticast ) ;
205
+ if ( result > resultToReturn )
206
+ resultToReturn = result ;
207
+ }
208
+
209
+ return resultToReturn ;
122
210
}
123
211
124
212
public Boolean IsConnected ( )
@@ -162,7 +250,7 @@ private void UdpReceiverLoop()
162
250
SplitCanPackets ( data , sourceAddress , port ) ;
163
251
}
164
252
}
165
- catch ( Exception ex ) {
253
+ catch {
166
254
Disconnect ( ) ;
167
255
}
168
256
}
0 commit comments