You've already forked lidgren-network-gen3
mirror of
https://github.com/lidgren/lidgren-network-gen3.git
synced 2026-05-17 15:46:33 +09:00
Added code to rebind socket after a NetConnected socket error; thanks Rhee
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER
|
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER && !UNITY_ANDROID && !UNITY_IPHONE
|
||||||
#define IS_MAC_AVAILABLE
|
#define IS_MAC_AVAILABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ namespace Lidgren.Network
|
|||||||
private object m_initializeLock = new object();
|
private object m_initializeLock = new object();
|
||||||
private uint m_frameCounter;
|
private uint m_frameCounter;
|
||||||
private double m_lastHeartbeat;
|
private double m_lastHeartbeat;
|
||||||
|
private double m_lastSocketBind = float.MinValue;
|
||||||
private NetUPnP m_upnp;
|
private NetUPnP m_upnp;
|
||||||
|
|
||||||
internal readonly NetPeerConfiguration m_configuration;
|
internal readonly NetPeerConfiguration m_configuration;
|
||||||
@@ -102,6 +103,46 @@ namespace Lidgren.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BindSocket(bool reBind)
|
||||||
|
{
|
||||||
|
double now = NetTime.Now;
|
||||||
|
if (now - m_lastSocketBind < 1.0)
|
||||||
|
{
|
||||||
|
LogDebug("Suppressed socket rebind; last bound " + (now - m_lastSocketBind) + " seconds ago");
|
||||||
|
return; // only allow rebind once every second
|
||||||
|
}
|
||||||
|
m_lastSocketBind = now;
|
||||||
|
|
||||||
|
if (m_socket == null)
|
||||||
|
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||||||
|
|
||||||
|
if (reBind)
|
||||||
|
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1);
|
||||||
|
|
||||||
|
m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize;
|
||||||
|
m_socket.SendBufferSize = m_configuration.SendBufferSize;
|
||||||
|
m_socket.Blocking = false;
|
||||||
|
|
||||||
|
var ep = (EndPoint)new IPEndPoint(m_configuration.LocalAddress, m_configuration.Port);
|
||||||
|
m_socket.Bind(ep);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const uint IOC_IN = 0x80000000;
|
||||||
|
const uint IOC_VENDOR = 0x18000000;
|
||||||
|
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
|
||||||
|
m_socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignore; SIO_UDP_CONNRESET not supported on this platform
|
||||||
|
}
|
||||||
|
|
||||||
|
IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint;
|
||||||
|
LogDebug("Socket bound to " + boundEp + ": " + m_socket.IsBound);
|
||||||
|
m_listenPort = boundEp.Port;
|
||||||
|
}
|
||||||
|
|
||||||
private void InitializeNetwork()
|
private void InitializeNetwork()
|
||||||
{
|
{
|
||||||
lock (m_initializeLock)
|
lock (m_initializeLock)
|
||||||
@@ -121,32 +162,7 @@ namespace Lidgren.Network
|
|||||||
m_handshakes.Clear();
|
m_handshakes.Clear();
|
||||||
|
|
||||||
// bind to socket
|
// bind to socket
|
||||||
IPEndPoint iep = null;
|
BindSocket(false);
|
||||||
|
|
||||||
iep = new IPEndPoint(m_configuration.LocalAddress, m_configuration.Port);
|
|
||||||
EndPoint ep = (EndPoint)iep;
|
|
||||||
|
|
||||||
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
|
||||||
m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize;
|
|
||||||
m_socket.SendBufferSize = m_configuration.SendBufferSize;
|
|
||||||
m_socket.Blocking = false;
|
|
||||||
m_socket.Bind(ep);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const uint IOC_IN = 0x80000000;
|
|
||||||
const uint IOC_VENDOR = 0x18000000;
|
|
||||||
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
|
|
||||||
m_socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignore; SIO_UDP_CONNRESET not supported on this platform
|
|
||||||
}
|
|
||||||
|
|
||||||
IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint;
|
|
||||||
LogDebug("Socket bound to " + boundEp + ": " + m_socket.IsBound);
|
|
||||||
m_listenPort = boundEp.Port;
|
|
||||||
|
|
||||||
m_receiveBuffer = new byte[m_configuration.ReceiveBufferSize];
|
m_receiveBuffer = new byte[m_configuration.ReceiveBufferSize];
|
||||||
m_sendBuffer = new byte[m_configuration.SendBufferSize];
|
m_sendBuffer = new byte[m_configuration.SendBufferSize];
|
||||||
@@ -175,6 +191,7 @@ namespace Lidgren.Network
|
|||||||
// not supported; lets just keep the random bytes set above
|
// not supported; lets just keep the random bytes set above
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint;
|
||||||
byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode());
|
byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode());
|
||||||
byte[] combined = new byte[epBytes.Length + macBytes.Length];
|
byte[] combined = new byte[epBytes.Length + macBytes.Length];
|
||||||
Array.Copy(epBytes, 0, combined, 0, epBytes.Length);
|
Array.Copy(epBytes, 0, combined, 0, epBytes.Length);
|
||||||
@@ -255,8 +272,19 @@ namespace Lidgren.Network
|
|||||||
{
|
{
|
||||||
m_socket.Shutdown(SocketShutdown.Receive);
|
m_socket.Shutdown(SocketShutdown.Receive);
|
||||||
}
|
}
|
||||||
catch { }
|
catch(Exception ex)
|
||||||
m_socket.Close(2); // 2 seconds timeout
|
{
|
||||||
|
LogDebug("Socket.Shutdown exception: " + ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_socket.Close(2); // 2 seconds timeout
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogDebug("Socket.Close exception: " + ex.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -270,6 +298,7 @@ namespace Lidgren.Network
|
|||||||
m_messageReceivedEvent.Set();
|
m_messageReceivedEvent.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_lastSocketBind = float.MinValue;
|
||||||
m_receiveBuffer = null;
|
m_receiveBuffer = null;
|
||||||
m_sendBuffer = null;
|
m_sendBuffer = null;
|
||||||
m_unsentUnconnectedMessages.Clear();
|
m_unsentUnconnectedMessages.Clear();
|
||||||
@@ -393,17 +422,24 @@ namespace Lidgren.Network
|
|||||||
}
|
}
|
||||||
catch (SocketException sx)
|
catch (SocketException sx)
|
||||||
{
|
{
|
||||||
if (sx.SocketErrorCode == SocketError.ConnectionReset)
|
switch (sx.SocketErrorCode)
|
||||||
{
|
{
|
||||||
// connection reset by peer, aka connection forcibly closed aka "ICMP port unreachable"
|
case SocketError.ConnectionReset:
|
||||||
// we should shut down the connection; but m_senderRemote seemingly cannot be trusted, so which connection should we shut down?!
|
// connection reset by peer, aka connection forcibly closed aka "ICMP port unreachable"
|
||||||
// So, what to do?
|
// we should shut down the connection; but m_senderRemote seemingly cannot be trusted, so which connection should we shut down?!
|
||||||
LogWarning("ConnectionReset");
|
// So, what to do?
|
||||||
return;
|
LogWarning("ConnectionReset");
|
||||||
}
|
return;
|
||||||
|
|
||||||
LogWarning(sx.ToString());
|
case SocketError.NotConnected:
|
||||||
return;
|
// socket is unbound; try to rebind it (happens on mobile when process goes to sleep)
|
||||||
|
BindSocket(true);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LogWarning("Socket exception: " + sx.ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesReceived < NetConstants.HeaderByteSize)
|
if (bytesReceived < NetConstants.HeaderByteSize)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace Lidgren.Network
|
|||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
public static ulong GetUInt64()
|
public static ulong GetUInt64()
|
||||||
{
|
{
|
||||||
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER
|
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER && !UNITY_ANDROID && !UNITY_IPHONE
|
||||||
ulong seed = (ulong)System.Diagnostics.Stopwatch.GetTimestamp();
|
ulong seed = (ulong)System.Diagnostics.Stopwatch.GetTimestamp();
|
||||||
seed ^= (ulong)Environment.WorkingSet;
|
seed ^= (ulong)Environment.WorkingSet;
|
||||||
ulong s2 = (ulong)Interlocked.Increment(ref m_seedIncrement);
|
ulong s2 = (ulong)Interlocked.Increment(ref m_seedIncrement);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRA
|
|||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER
|
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER && !UNITY_ANDROID && !UNITY_IPHONE
|
||||||
#define IS_FULL_NET_AVAILABLE
|
#define IS_FULL_NET_AVAILABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -599,7 +599,7 @@ namespace Lidgren.Network
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static byte[] CreateSHA1Hash(string key)
|
public static byte[] CreateSHA1Hash(string key)
|
||||||
{
|
{
|
||||||
using (var sha = SHA1.Create())
|
using (var sha = new SHA1CryptoServiceProvider())
|
||||||
return sha.ComputeHash(Encoding.UTF8.GetBytes(key));
|
return sha.ComputeHash(Encoding.UTF8.GetBytes(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,7 +608,7 @@ namespace Lidgren.Network
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static byte[] CreateSHA1Hash(byte[] data)
|
public static byte[] CreateSHA1Hash(byte[] data)
|
||||||
{
|
{
|
||||||
using (var sha = SHA1.Create())
|
using (var sha = new SHA1CryptoServiceProvider())
|
||||||
return sha.ComputeHash(data);
|
return sha.ComputeHash(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,6 @@
|
|||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
</Compile>
|
</Compile>
|
||||||
<None Include="app.config" />
|
|
||||||
<None Include="Properties\Settings.settings">
|
<None Include="Properties\Settings.settings">
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
|||||||
@@ -95,7 +95,6 @@
|
|||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
</Compile>
|
</Compile>
|
||||||
<None Include="app.config" />
|
|
||||||
<None Include="Properties\Settings.settings">
|
<None Include="Properties\Settings.settings">
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
|||||||
Reference in New Issue
Block a user