/// <summary> /// クライアントに文字列のメッセージを送信する /// </summary> /// <param name="stream"></param> /// <param name="message"></param> private void SendMessage(ClientContext context, string message) { Stream stream = context.tcpClient.GetStream(); BinaryWriter writer = new BinaryWriter(stream); byte[] byteArray = Encoding.UTF8.GetBytes(message); try { writer.Write(byteArray.Length); writer.Write(byteArray); writer.Flush(); } catch (IOException) { invokeServerEvent("SendMessage() で例外が発生しました。クライアントを切断します。"); CloseClient(context); } }
/// <summary> /// データ受信 /// </summary> /// <param name="context"></param> /// <param name="stream"></param> private void ReadStream(ClientContext context, NetworkStream stream) { BinaryReader reader = new BinaryReader(stream); // 受信タイムアウト時間の設定 stream.ReadTimeout = 1000; // ブロッキングモードでデータを受信 while (stream.DataAvailable) { try { byte type = reader.ReadByte(); switch (type) { case 2: int size = reader.ReadInt32(); byte[] byteArray = reader.ReadBytes(size); string str = Encoding.UTF8.GetString(byteArray); if (context.tcpClient.Client.Connected == false) break; string message = context.tcpClient.Client.RemoteEndPoint.ToString() + " : " + str; invokeServerEvent(message); SendMessageAll(message); break; } } catch (EndOfStreamException) { invokeServerEvent("ReadStream() で例外が発生しました。クライアントを切断します。"); context.StopFlag = true; CloseClient(context); break; } catch (IOException) { // タイムアウト invokeServerEvent("ReadStream() で例外が発生しました。クライアントを切断します。"); context.StopFlag = true; CloseClient(context); break; } } }
/// <summary> /// サーバ待ち受けループ /// </summary> private void Listen() { tcpListener = new TcpListener(IPAddress.Any, Port); tcpListener.Start(); invokeServerEvent("接続を待っています。"); while (!StopFlag) { if (tcpListener.Pending()) { try { Thread thread = new Thread(new ParameterizedThreadStart(ClientLoop)); TcpClient client = tcpListener.AcceptTcpClient(); ClientContext context = new ClientContext(client, thread); clients.Add(context); if (context.tcpClient.Connected == false) { CloseClient(context); continue; } //SendMessage(context, "サーバからのメッセージ : 接続しました"); thread.Start(context); invokeServerEvent("クライアントが接続しました。 : " + client.Client.RemoteEndPoint.ToString()); invokeServerEvent("現在の接続数: " + clients.Count); } catch (SocketException e) { invokeServerEvent("エラー (SocketException) : " + e.ToString()); continue; } } Thread.Sleep(10); } tcpListener.Stop(); }
/// <summary> /// クライアントを切断する /// </summary> /// <param name="context"></param> private void CloseClient(ClientContext context) { clients.Remove(context); //invokeServerEvent("クライアントの接続を閉じました。 : " + context.tcpClient.Client.RemoteEndPoint.ToString()); invokeServerEvent("クライアントの接続を閉じました。"); invokeServerEvent("現在の接続数: " + clients.Count); }
/// <summary> /// データ受信 /// </summary> /// <param name="context"></param> /// <param name="stream"></param> private void ReadStream(ClientContext context, NetworkStream stream) { BinaryReader reader = new BinaryReader(stream); // 受信タイムアウト時間の設定 //stream.ReadTimeout = 1000; // ブロッキングモードでデータを受信 while (stream.DataAvailable) { List<byte> byteList = new List<byte>(); // 1 文字ずつ、 \0 が出現するまで読み取る // 例外が出たときも読み取り終了 while (true) { byte buffer; try { buffer = (byte)stream.ReadByte(); } catch (IOException) { break; } if (buffer == 0) break; byteList.Add(buffer); } // 読み取ったデータをストリング型に変換 string message = Encoding.UTF8.GetString(byteList.ToArray()); byteList.Clear(); try { // 受信したデータが、<policy-file-request/> だった時 if (message == "<policy-file-request/>") { invokeServerEvent("PolicyFileServer : ポリシーファイルを送信します。"); SendMessage(context, Policy); CloseClient(context); break; } } catch (EndOfStreamException) { invokeServerEvent("PolicyFileServer : ReadStream() で例外が発生しました。クライアントを切断します。"); context.StopFlag = true; CloseClient(context); break; } catch (IOException e) { // タイムアウト invokeServerEvent("PolicyFileServer : ReadStream() で例外が発生しました。クライアントを切断します。"); invokeServerEvent(e.ToString()); context.StopFlag = true; CloseClient(context); break; } } }
/// <summary> /// クライアントを切断する /// </summary> /// <param name="context"></param> private void CloseClient(ClientContext context) { context.tcpClient.Close(); clients.Remove(context); invokeServerEvent("クライアントの接続を閉じました。"); invokeServerEvent("現在の接続数: " + clients.Count); }