1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
using System;
using System.Net;
namespace Hazel.Udp
{
/// <summary>
/// Represents a servers's connection to a client that uses the UDP protocol.
/// </summary>
/// <inheritdoc/>
internal sealed class UdpServerConnection : UdpConnection
{
/// <summary>
/// The connection listener that we use the socket of.
/// </summary>
/// <remarks>
/// Udp server connections utilize the same socket in the listener for sends/receives, this is the listener that
/// created this connection and is hence the listener this conenction sends and receives via.
/// </remarks>
public UdpConnectionListener Listener { get; private set; }
/// <summary>
/// Creates a UdpConnection for the virtual connection to the endpoint.
/// </summary>
/// <param name="listener">The listener that created this connection.</param>
/// <param name="endPoint">The endpoint that we are connected to.</param>
/// <param name="IPMode">The IPMode we are connected using.</param>
internal UdpServerConnection(UdpConnectionListener listener, IPEndPoint endPoint, IPMode IPMode, ILogger logger)
: base(logger)
{
this.Listener = listener;
this.EndPoint = endPoint;
this.IPMode = IPMode;
State = ConnectionState.Connected;
this.InitializeKeepAliveTimer();
}
/// <inheritdoc />
protected override void WriteBytesToConnection(byte[] bytes, int length)
{
this.Statistics.LogPacketSend(length);
Listener.SendData(bytes, length, EndPoint);
}
/// <inheritdoc />
/// <remarks>
/// This will always throw a HazelException.
/// </remarks>
public override void Connect(byte[] bytes = null, int timeout = 5000)
{
throw new InvalidOperationException("Cannot manually connect a UdpServerConnection, did you mean to use UdpClientConnection?");
}
/// <inheritdoc />
/// <remarks>
/// This will always throw a HazelException.
/// </remarks>
public override void ConnectAsync(byte[] bytes = null)
{
throw new InvalidOperationException("Cannot manually connect a UdpServerConnection, did you mean to use UdpClientConnection?");
}
/// <summary>
/// Sends a disconnect message to the end point.
/// </summary>
protected override bool SendDisconnect(MessageWriter data = null)
{
lock (this)
{
if (this._state != ConnectionState.Connected)
{
return false;
}
this._state = ConnectionState.NotConnected;
}
var bytes = EmptyDisconnectBytes;
if (data != null && data.Length > 0)
{
if (data.SendOption != SendOption.None) throw new ArgumentException("Disconnect messages can only be unreliable.");
bytes = data.ToByteArray(true);
bytes[0] = (byte)UdpSendOption.Disconnect;
}
try
{
Listener.SendDataSync(bytes, bytes.Length, EndPoint);
}
catch { }
return true;
}
protected override void Dispose(bool disposing)
{
Listener.RemoveConnectionTo(EndPoint);
if (disposing)
{
SendDisconnect();
}
base.Dispose(disposing);
}
}
}
|