• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

ソケットを使ってクライアントサーバプログラムを作成するための C# ライブラリ


Commit MetaInfo

Revisão9a76071abc774fa4353d49f89c276fe25491f5fb (tree)
Hora2015-08-14 23:30:40
Autortsntsumi <tsntsumi@tsnt...>
Commitertsntsumi

Mensagem de Log

TcpConnection と TcpServer の共通データを独立させる修正

TcpConnection 内部で使用する HeaderLength, FooterLength,
ObtainPayloadLength は、生成する際にオプションとして引数で指
定可能としている。TcpServer では、パケットの受信に
TcpConnection を生成して使用するため、同様のデータをオプショ
ン引数で指定しなければならなかった。そのため、デフォルトの値
を二重に管理しなければならなかった。

そこで、デフォルトの値を、新規に作成した Packet クラスのオブ
ジェクトで管理するように変更した。

Mudança Sumário

Diff

--- a/src/SocketNet/SampleChatClient/ChatClient.cs
+++ b/src/SocketNet/SampleChatClient/ChatClient.cs
@@ -106,8 +106,7 @@ namespace SampleChatClient
106106 RemoteIPAddress = serverIPAddress;
107107 RemotePort = serverPort;
108108 client.Connect(RemoteIPAddress, RemotePort);
109- Connection = new TcpConnection(client.Client,
110- ChatMessage.HeaderLength, ChatMessage.FooterLength, ChatMessage.ObtainPayloadLength);
109+ Connection = new TcpConnection(client.Client, new ChatMessage());
111110 Connection.DataReceived += OnDataReceived;
112111 }
113112 }
--- a/src/SocketNet/SampleChatClient/ChatMessage.cs
+++ b/src/SocketNet/SampleChatClient/ChatMessage.cs
@@ -8,10 +8,9 @@ namespace SampleChatClient
88 /// <summary>
99 /// <see cref="ChatServer"/> と <see cref="ChatClient"/> 間で送受信されるチャットメッセージを表します。
1010 /// </summary>
11- public class ChatMessage
11+ public class ChatMessage: Packet
1212 {
13- public const int HeaderLength = 2;
14- public const int FooterLength = 0;
13+ public override int HeaderLength { get { return 2; } }
1514
1615 /// <summary>
1716 /// メッセージを送受信する接続を取得または設定します。
@@ -26,6 +25,13 @@ namespace SampleChatClient
2625 /// <summary>
2726 /// コンストラクタ。
2827 /// </summary>
28+ public ChatMessage()
29+ {
30+ }
31+
32+ /// <summary>
33+ /// コンストラクタ。
34+ /// </summary>
2935 /// <param name="message">メッセージ文字列。</param>
3036 /// <param name="connection">接続。</param>
3137 public ChatMessage(string message, TcpConnection connection = null)
@@ -39,7 +45,7 @@ namespace SampleChatClient
3945 /// </summary>
4046 /// <returns>ペイロード長。</returns>
4147 /// <param name="header">ヘッダ。</param>
42- public static int ObtainPayloadLength(byte[] header)
48+ public override int ObtainPayloadLength(byte[] header)
4349 {
4450 int payloadLength = header[0] << 8 | header[1];
4551
@@ -53,14 +59,15 @@ namespace SampleChatClient
5359 /// <param name="data">バイト配列データ。</param>
5460 public static ChatMessage FromByteArray(byte[] data)
5561 {
62+ ChatMessage chatMessage = new ChatMessage();
5663 Encoding encoding = new UTF8Encoding(false);
5764 // int length = (data[0] << 8) | data[1];
58- byte[] messageData = new byte[data.Length - HeaderLength];
65+ byte[] messageData = new byte[data.Length - chatMessage.HeaderLength];
5966
60- Array.Copy(data, HeaderLength, messageData, 0, messageData.Length);
61- string message = encoding.GetString(messageData);
67+ Array.Copy(data, chatMessage.HeaderLength, messageData, 0, messageData.Length);
68+ chatMessage.Message = encoding.GetString(messageData);
6269
63- return new ChatMessage(message);
70+ return chatMessage;
6471 }
6572
6673 /// <summary>
--- a/src/SocketNet/SampleChatServer/ChatServer.cs
+++ b/src/SocketNet/SampleChatServer/ChatServer.cs
@@ -41,8 +41,7 @@ namespace SampleChatServer
4141 /// <param name="port">待ち受けするポート番号。</param>
4242 public ChatServer (IPAddress ipAddress, int port)
4343 {
44- tcpServer = new TcpServer(ipAddress, port,
45- ChatMessage.HeaderLength, ChatMessage.FooterLength, ChatMessage.ObtainPayloadLength);
44+ tcpServer = new TcpServer(ipAddress, port, new ChatMessage());
4645 tcpServer.Connected += OnConnected;
4746 tcpServer.Disconnected += OnDisconnected;
4847 tcpServer.DataReceived += OnDataReceived;
--- /dev/null
+++ b/src/SocketNet/SocketNet/Packet.cs
@@ -0,0 +1,27 @@
1+using System;
2+
3+namespace SocketNet
4+{
5+ public class Packet
6+ {
7+ public virtual int HeaderLength { get { return 4; } }
8+ public virtual int FooterLength { get { return 0; } }
9+
10+ public virtual int ObtainPayloadLength(byte[] header)
11+ {
12+ int payloadLength = 0;
13+
14+ if (header.Length < HeaderLength)
15+ {
16+ return 0;
17+ }
18+ for (int i = 0; i < HeaderLength; i++)
19+ {
20+ payloadLength = (payloadLength << 8) | header[i];
21+ }
22+
23+ return payloadLength;
24+ }
25+ }
26+}
27+
--- a/src/SocketNet/SocketNet/SocketNet.csproj
+++ b/src/SocketNet/SocketNet/SocketNet.csproj
@@ -36,6 +36,7 @@
3636 <Compile Include="TcpConnectionEventArgs.cs" />
3737 <Compile Include="TcpDataReceivedEventArgs.cs" />
3838 <Compile Include="TcpServer.cs" />
39+ <Compile Include="Packet.cs" />
3940 </ItemGroup>
4041 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
4142 </Project>
\ No newline at end of file
--- a/src/SocketNet/SocketNet/TcpConnection.cs
+++ b/src/SocketNet/SocketNet/TcpConnection.cs
@@ -32,9 +32,7 @@ namespace SocketNet
3232 public sealed class TcpConnection: IDisposable
3333 {
3434 private static readonly int ReceivedDataBufferSize = 65535;
35- private readonly int PacketHeaderLength;
36- private readonly int PacketFooterLength;
37- private readonly ObtainPayloadLengthDelegate ObtainPayloadLength;
35+ private readonly Packet Packet = new Packet();
3836
3937 private object syncObject;
4038 private NetworkStream networkStream;
@@ -111,14 +109,8 @@ namespace SocketNet
111109 /// コンストラクタ。
112110 /// </summary>
113111 /// <param name="client">ソケット。</param>
114- /// <param name="headerLength">パケットヘッダ長。</param>
115- /// <param name="footerLength">パケットフッダ長。</param>
116- /// <param name="obtainPayloadLength">ペイロード長取得デリゲート。</param>
117- public TcpConnection(
118- Socket client,
119- int headerLength = 4,
120- int footerLength = 0,
121- ObtainPayloadLengthDelegate obtainPayloadLength = null)
112+ /// <param name="packet">受信するパケットの各部の長さの設定を格納するオブジェクト。</param>
113+ public TcpConnection(Socket client, Packet packet)
122114 {
123115 syncObject = new object();
124116 Client = client;
@@ -126,50 +118,17 @@ namespace SocketNet
126118 Reader = new BinaryReader(networkStream);
127119 Writer = new BinaryWriter(networkStream);
128120
129- PacketHeaderLength = headerLength;
130- PacketFooterLength = footerLength;
131-
132- if (obtainPayloadLength == null)
133- {
134- ObtainPayloadLength = ObtainPayloadLengthFromHeader;
135- }
136- else
137- {
138- ObtainPayloadLength = obtainPayloadLength;
139- }
121+ Packet = packet;
140122
141123 partiallyReceivedData = new byte[ReceivedDataBufferSize];
142124 completelyReceivedData = new List<byte>();
143- header = new byte[headerLength];
125+ header = new byte[Packet.HeaderLength];
144126 packet = null;
145127 packetPayloadLength = 0;
146128 bytesToProcessRemaining = 0;
147129 }
148130
149131 /// <summary>
150- /// パケットのペイロード長を、ヘッダから計算して返します
151- /// </summary>
152- /// <returns>ペイロード長。</returns>
153- /// <param name="header">ヘッダを含む配列。</param>
154- /// <remarks>
155- /// ヘッダの先頭に4バイトのペイロード長があるとして、int 型に変換して返します。
156- /// </remarks>
157- private int ObtainPayloadLengthFromHeader(byte[] header)
158- {
159- if (header.Length < 4)
160- {
161- return 0;
162- }
163- int payloadLength = 0;
164- for (int i = 0; i < 4; i++)
165- {
166- payloadLength = (payloadLength << 8) | header[i];
167- }
168-
169- return payloadLength;
170- }
171-
172- /// <summary>
173132 /// 関連付けられたリソースを解放します。
174133 /// </summary>
175134 public void Dispose()
@@ -278,14 +237,14 @@ namespace SocketNet
278237 switch (receiveState)
279238 {
280239 case DataReceiveState.PacketHeader:
281- if (completelyReceivedData.Count >= PacketHeaderLength)
240+ if (completelyReceivedData.Count >= Packet.HeaderLength)
282241 {
283- completelyReceivedData.CopyTo(0, header, 0, PacketHeaderLength);
284- packetPayloadLength = ObtainPayloadLength(header);
242+ completelyReceivedData.CopyTo(0, header, 0, Packet.HeaderLength);
243+ packetPayloadLength = Packet.ObtainPayloadLength(header);
285244
286245 receiveState = DataReceiveState.PacketPayload;
287- completelyReceivedData.RemoveRange(0, PacketHeaderLength);
288- bytesToProcessRemaining -= PacketHeaderLength;
246+ completelyReceivedData.RemoveRange(0, Packet.HeaderLength);
247+ bytesToProcessRemaining -= Packet.HeaderLength;
289248 }
290249 else
291250 {
@@ -296,15 +255,15 @@ namespace SocketNet
296255 case DataReceiveState.PacketPayload:
297256 if (completelyReceivedData.Count >= packetPayloadLength)
298257 {
299- packet = new byte[PacketHeaderLength + packetPayloadLength + PacketFooterLength];
300- Array.Copy(header, packet, PacketHeaderLength);
301- completelyReceivedData.CopyTo(0, packet, PacketHeaderLength, packetPayloadLength);
258+ packet = new byte[Packet.HeaderLength + packetPayloadLength + Packet.FooterLength];
259+ Array.Copy(header, packet, Packet.HeaderLength);
260+ completelyReceivedData.CopyTo(0, packet, Packet.HeaderLength, packetPayloadLength);
302261
303262 receiveState = DataReceiveState.PacketFooter;
304263 completelyReceivedData.RemoveRange(0, packetPayloadLength);
305264 bytesToProcessRemaining -= packetPayloadLength;
306265
307- if (PacketFooterLength == 0)
266+ if (Packet.FooterLength == 0)
308267 {
309268 OnDataReceived(new TcpDataReceivedEventArgs(this, packet));
310269 receiveState = DataReceiveState.PacketHeader;
@@ -317,15 +276,15 @@ namespace SocketNet
317276 break;
318277
319278 case DataReceiveState.PacketFooter:
320- if (completelyReceivedData.Count >= PacketFooterLength)
279+ if (completelyReceivedData.Count >= Packet.FooterLength)
321280 {
322- completelyReceivedData.CopyTo(0, packet, PacketHeaderLength + packetPayloadLength, PacketFooterLength);
281+ completelyReceivedData.CopyTo(0, packet, Packet.HeaderLength + packetPayloadLength, Packet.FooterLength);
323282
324283 OnDataReceived(new TcpDataReceivedEventArgs(this, packet));
325284
326285 receiveState = DataReceiveState.PacketHeader;
327- completelyReceivedData.RemoveRange(0, PacketFooterLength);
328- bytesToProcessRemaining -= PacketFooterLength;
286+ completelyReceivedData.RemoveRange(0, Packet.FooterLength);
287+ bytesToProcessRemaining -= Packet.FooterLength;
329288 }
330289 else
331290 {
--- a/src/SocketNet/SocketNet/TcpServer.cs
+++ b/src/SocketNet/SocketNet/TcpServer.cs
@@ -38,9 +38,7 @@ namespace SocketNet
3838 /// </summary>
3939 public static readonly int MaxPendingConnections = 3;
4040
41- private readonly int PacketHeaderLength;
42- private readonly int PacketFooterLength;
43- private readonly TcpConnection.ObtainPayloadLengthDelegate ObtainPayloadLength;
41+ private readonly Packet Packet;
4442
4543 private TcpListener tcpListener;
4644 private List<TcpConnection> clientConnections;
@@ -115,18 +113,12 @@ namespace SocketNet
115113 /// コンストラクタ。
116114 /// </summary>
117115 /// <param name="port">バインドするポート。</param>
118- /// <param name="headerLength">ヘッダの長さ。</param>
119- /// <param name="footerLength">フッタの長さ。</param>
120- /// <param name="obtainPayloadLength">ペイロード長取得デリゲート。</param>
116+ /// <param name="packet">受信するパケットの各部の長さの設定を格納するオブジェクト。</param>
121117 /// <remarks>
122118 /// ループバックアドレスを使用します。
123119 /// </remarks>
124- public TcpServer(
125- int port,
126- int headerLength = 4,
127- int footerLength = 0,
128- TcpConnection.ObtainPayloadLengthDelegate obtainPayloadLength = null)
129- : this(IPAddress.Loopback, port, headerLength, footerLength, obtainPayloadLength)
120+ public TcpServer(int port, Packet packet)
121+ : this(IPAddress.Loopback, port, packet)
130122 {
131123 }
132124
@@ -135,22 +127,12 @@ namespace SocketNet
135127 /// </summary>
136128 /// <param name="ipAddress">バインドするIPアドレス。</param>
137129 /// <param name="port">バインドするポート。</param>
138- /// <param name="headerLength">ヘッダの長さ。</param>
139- /// <param name="footerLength">フッタの長さ。</param>
140- /// <param name="obtainPayloadLength">ペイロード長取得デリゲート。</param>
141- public TcpServer(
142- IPAddress ipAddress,
143- int port,
144- int headerLength = 4,
145- int footerLength = 0,
146- TcpConnection.ObtainPayloadLengthDelegate obtainPayloadLength = null)
130+ /// <param name="packet">受信するパケットの各部の長さの設定を格納するオブジェクト。</param>
131+ public TcpServer(IPAddress ipAddress, int port, Packet packet)
147132 {
148- PacketHeaderLength = headerLength;
149- PacketFooterLength = footerLength;
150- ObtainPayloadLength = obtainPayloadLength;
151-
152- Port = port;
153133 IPAddress = ipAddress;
134+ Port = port;
135+ Packet = packet;
154136 clientConnections = new List<TcpConnection>();
155137 connectionsToClose = new List<TcpConnection>();
156138 isShuttingDown = false;
@@ -231,8 +213,7 @@ namespace SocketNet
231213
232214 await Task.Run(() =>
233215 {
234- TcpConnection connection = new TcpConnection(
235- socket, PacketHeaderLength, PacketFooterLength, ObtainPayloadLength);
216+ TcpConnection connection = new TcpConnection(socket, Packet);
236217 connection.Disconnected += new EventHandler<TcpConnectionEventArgs>(OnDisconnected);
237218 connection.DataReceived += new EventHandler<TcpDataReceivedEventArgs>(OnDataReceived);
238219