Catcher in the Error

だれか私をつかまえて

.NETでTCP/IP通信

・趣味でXamarinいじいじ
AndroidTCP/IP通信したろ!と思う
・とりあえずコンソールアプリで簡単なクライアントとサーバーを作成したのでまとめ。

サーバー側

以下を参考にさせていただいて作成。
雑なHTTPサーバーをC#で書いてみる - ぷろじぇくと、みすじら。

コード
    static async void RunServer()
    {
        var ip = IPAddress.Parse("192.168.102.123");
        var port = 12345;

        var tcpListener = new TcpListener(ip, port);

        tcpListener.Start();

        while (true)
        {
            using (var tcpClient = await tcpListener.AcceptTcpClientAsync())
            using (var stream = tcpClient.GetStream())
            using (var reader = new StreamReader(stream))
            using (var writer = new StreamWriter(stream))
            {
                // 接続元
                Console.WriteLine(tcpClient.Client.RemoteEndPoint);

                string line;
                do
                {
                    line = await reader.ReadLineAsync();
                    // 受信メッセージ
                    if (line != "")
                    {
                        Console.WriteLine($"recieve message:{line}");
                    };

                } while (!String.IsNullOrWhiteSpace(line));

                // 返信
                await writer.WriteLineAsync("Server has recieved your message"); 
                await writer.WriteLineAsync(); // 終わり
            }

            Console.WriteLine("end connection");
        }
    }

 

クライアント側

サーバー作成で参考にしたサイトではクライアント側の例がないのでてきとーにググる
しかし、検索結果にでてくるのはNetStreamからバイト配列取得してエンコードしてという例ばかり。
StreamWriterとStreamReaderがよろしくやってくれるほうがいい!と思ってサーバー側をもとにクライアント側も作成してみたが動かない。
具体的には以下のように書いてもmsgが送信されない。

    using (var writer = new StreamWriter(stream)
    {
        await writer.WriteLineAsync(msg);
        await writer.WriteLineAsync();
    }


しばらくMSDNとにらめっこしているとそれっぽいメソッドがあったので呼び出したら無事送信された。

    using (var writer = new StreamWriter(stream))
    {
        await writer.WriteLineAsync(msg);
        await writer.WriteLineAsync();

        // このストリームのすべてのバッファーを非同期にクリアし、
        //バッファー内のデータを基になるデバイスに書き込みます。とのこと
        await writer.FlushAsync();
    }


でもなんでサーバー側はFlushAsync()なしで送信できてるんですかね?っていう疑問は残りましたとさ。
そのうちわかったらまた記事にしようかと思います。

コード
    public async void RunClient()
    {
        Console.WriteLine("入力してください");
        string msg = Console.ReadLine();

        string ip = "192.168.102.123";
        int port = 12345;

        using (var tcpClient = new TcpClient(ip, port))
        using (var stream = tcpClient.GetStream())
        using (var reader = new StreamReader(stream))
        using (var writer = new StreamWriter(stream))
        {
            Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})。",
            ((System.Net.IPEndPoint)tcpClient.Client.RemoteEndPoint).Address,
            ((System.Net.IPEndPoint)tcpClient.Client.RemoteEndPoint).Port,
            ((System.Net.IPEndPoint)tcpClient.Client.LocalEndPoint).Address,
            ((System.Net.IPEndPoint)tcpClient.Client.LocalEndPoint).Port);

            await writer.WriteLineAsync(msg);
            await writer.WriteLineAsync();

            await writer.FlushAsync();

            string line;
            do
            {
                line = await reader.ReadLineAsync();
                // 受信メッセージ
                if (line != "") Console.WriteLine($"message form Server:{line}");

            } while (!String.IsNullOrWhiteSpace(line));
        }

        Console.WriteLine("end connection");
    }