StreamSoketのSampleコード

非同期化していないところがあったりするのであまりいいサンプルではないですが、StreamSoketでの通信コードです。
WriteAsync、LoadAsyncで書き込み/読み込みを行うようにしてあります。
DataReader、DataWriterを使用した際にうまくいかなかったので、このような形で実装しています。

///////////////////////////////////////////////////////////////////////////////////////////////
// サーバへ接続等

        #region サーバへ接続
        /// <summary>
        /// TCPでサーバへ接続
        /// </summary>
        /// <param name="hostname"></param>
        /// <param name="serverport"></param>
        public async void TcpSocketConnect(string hostname, string serverport)
        {
            SocketStatusEventArgs socketevent = new SocketStatusEventArgs();

            // 接続済み
            if (SocketDatacontext.Connected)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Already");
                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                await Task.Run(() => { throw new PopClassException(SocketDatacontext.SocketMessage); });
                return;
            }

            if (SocketDatacontext.TcpSocket == null)
            {
                SocketDatacontext.TcpSocket = new Windows.Networking.Sockets.StreamSocket();

                bool currentSetting = SocketDatacontext.TcpSocket.Control.NoDelay;
                SocketDatacontext.TcpSocket.Control.KeepAlive = true;
                SocketDatacontext.TcpSocket.Control.NoDelay = false;
            }

            try
            {
                /// タイムアウト用
                CancellationTokenSource cts = new CancellationTokenSource();

                socketevent.SocketStatus = StringResourceLoader.GetString("Trying");

                OnSocketStatus(socketevent);

                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus); 
                
                var serverHost = new HostName(hostname);

                // タイムアウトの設定
                cts.CancelAfter(10000);

                await SocketDatacontext.TcpSocket.ConnectAsync(serverHost, serverport).AsTask(cts.Token);

                // DataReaderの作成
                SocketDatacontext.PeerReader = new DataReader(SocketDatacontext.TcpSocket.InputStream);
                SocketDatacontext.PeerReader.InputStreamOptions = InputStreamOptions.Partial;

                SocketDatacontext.Connected = true;
                SocketDatacontext.Closing = false;
                socketevent.SocketStatus = StringResourceLoader.GetString("Connection");
                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
            }
            catch (Exception ex)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Connecterror") + ex.Message;
                OnSocketStatus(socketevent);

                SocketDatacontext.Closing = true;
                SocketDatacontext.TcpSocket.Dispose();
                SocketDatacontext.TcpSocket = null;
                SocketDatacontext.Connected = false;

                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                throw new PopClassException(SocketDatacontext.SocketMessage);
            }
        }
        #endregion

///////////////////////////////////////////////////////////////////////////////////////////////
// サーバへデータを送る

        #region サーバへデータを送る
        public async void ResultSend(string req)
        {
            SocketStatusEventArgs socketevent = new SocketStatusEventArgs();

            if (!SocketDatacontext.Connected)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Mustbeconnectedtosend");
                OnSocketStatus(socketevent);

                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                return;
            }

            try
            {
                // サーバへリクエスト送信
                if (req != "")
                {
                    StreamSocketLib writeSokect = new StreamSocketLib();

                    socketevent.SocketStatus = StringResourceLoader.GetString("Tryingtosenddata");
                    OnSocketStatus(socketevent);

                    writeSokect.DataSend(SocketDatacontext.TcpSocket, req);

                    cryearthlib.DebugLoging.DebugPrint("Data Writer End");
                }
            }
            catch (Exception exception)
            {
                socketevent.SocketStatus = "Send data or receive failed with error: " + exception.Message;
                OnSocketStatus(socketevent);
            }
        }
        #endregion
        /// <summary>
        /// データ書き込みフロント
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="senddata"></param>
        public void DataSend(StreamSocket socket, string req)
        {
            _socket = socket;

            Encoding encoding = Encoding.UTF8;

            byte[] bydata = encoding.GetBytes(req + Environment.NewLine);

            if (socket == null)
            {
                cryearthlib.DebugLoging.DebugPrint("socket Error : socket null");
                throw new Exception("socket Error : socket null");
            }

            try
            {
                var task = SocketDataWrite(bydata);
                if (!task.IsCompleted)
                {
                    var ret = task.Wait(timeout);
                    if (!ret)
                    {
                        cryearthlib.DebugLoging.DebugPrint("Write Time Out");
                    }
                }

                if (!task.Result)
                {
                    cryearthlib.DebugLoging.DebugPrint("Write Time Out");
                }
            }
            catch (Exception ex)
            {
                cryearthlib.DebugLoging.DebugPrint("DataWrite Error : " + ex.Message);
                throw new Exception("DataWrite Error : " + ex.Message);
            }
        }

        /// <summary>
        /// データ書き込み本体
        /// </summary>
        /// <param name="senddata"></param>
        /// <returns></returns>
        public async Task<bool> SocketDataWrite(byte[] senddata)
        {
            var writeTask = _socket.OutputStream.WriteAsync(senddata.AsBuffer()).AsTask();

            if (!writeTask.IsCompleted)
            {
                var writeret = writeTask.Wait(timeout);
                if (!writeret)
                {
                    return false;
                }
            }

            var flushTask = _socket.OutputStream.FlushAsync().AsTask();

            if (!flushTask.IsCompleted)
            {
                var flushret = flushTask.Wait(timeout);
                if (!flushret)
                {
                    return false;
                }
            }
            return true;
        }



///////////////////////////////////////////////////////////////////////////////////////////////
// サーバからのデータを読み込む

        #region サーバからのデータを読み込む
        public async Task<string> ResultRead()
        {
            SocketStatusEventArgs socketevent = new SocketStatusEventArgs();

            if (!SocketDatacontext.Connected)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Mustbeconnectedtosend");
                OnSocketStatus(socketevent);

                return null;
            }

            try
            {
                var lastChar = string.Empty;
                var fullString = string.Empty;

                cryearthlib.Sleep(200);
                
                socketevent.SocketStatus = StringResourceLoader.GetString("Tryingtosenddata");
                OnSocketStatus(socketevent);

                CancellationTokenSource cts = new CancellationTokenSource(1000);
                cts.Token.ThrowIfCancellationRequested();
                var bytesRead = SocketDatacontext.PeerReader.LoadAsync(1024);

                Debug.WriteLine("StreamWriteAndRead : reader.LoadAsync : " + bytesRead.Status.ToString());

                if (bytesRead.Status != Windows.Foundation.AsyncStatus.Completed)
                {
                    cts.Cancel();

                    Debug.WriteLine("StreamWriteAndRead : cts.Cancel");
                    Debug.WriteLine("StreamWriteAndRead : " + bytesRead.Status.ToString());
                }
                else
                {
                    Debug.WriteLine("StreamWriteAndRead : ReadString : " + bytesRead.Status.ToString());

                    while (SocketDatacontext.PeerReader.UnconsumedBufferLength > 0)
                    {
                        fullString += SocketDatacontext.PeerReader.ReadString(SocketDatacontext.PeerReader.UnconsumedBufferLength);
                    }
                }

                SocketDatacontext.SocketMessage = socketevent.SocketStatus = fullString;
                OnSocketStatus(socketevent);

                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                cryearthlib.DebugLoging.DebugPrint("reader.End");
                return fullString;
            }
            catch (Exception exception)
            {
                socketevent.SocketStatus = "Receive failed with error: " + exception.Message;
                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                return socketevent.SocketStatus;
            }
        }
#endregion

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください