Top > プログラミング > .NET Tips> TCPクライアント・サーバープログラムを作成する

TCPクライアント・サーバープログラムを作成する」への評価、コメント

評価

良い / 悪い = 129 / 8 (「良い」の割合 = 0.942 , 人気度 = 2.013

評価する

コメント一覧


評価の理由
匿名 2022/11/23 (Wed) 17:09:11
評価:良い
いつも参考にさせて頂いております!
今回も大いに助けになりました!
ありがとうございます!

評価の理由
匿名 2022/10/31 (Mon) 17:08:15
評価:悪い
ns.DataAvailable を見てループを抜けるのはやめたほうがいいです。
というのは、パケット長が長くなり、長さが MTU値を超えると分割して送信されるからです。
つまり、データはまだ続いているのに、受信途中で抜けてしまう可能性があります。

通常のコメント
匿名 2022/06/27 (Mon) 19:40:10
他サイトのサンプルを複数見ながら作ったTcpServerプログラムが受信と返信の2回目以降が例外になってしまい四苦八苦していたところ、ここでヒントを得てなんとか仕事を進められた。ありがとうございます。

通常のコメント
あばば無人君 2021/03/10 (Wed) 11:37:33
いつも当サイトでお勉強をさせて頂いております。

「すべてのIPアドレスをListenする」の箇所で
IPv4とIPv6のアドレスをListenする方法として
 IPAddress.IPv6Anyの指定 &
 Socket.SetSocketOptionメソッドでIPv6Onlyを0にする
と記載されていますが、最近?はこれを一つにまとめた
 TcpListener listener = TcpListener.Create(ポート番号);
という方法もありますので参考になればと思い
コメントさせていただきました。

以上です。宜しくお願い致します。

通常のコメント
匿名 2019/08/12 (Mon) 13:03:05
もっと読みやすくしてくれ

通常のコメント
匿名 2019/05/22 (Wed) 21:37:17
>>以下に示すコンソールアプリケーションは、ローカルIPアドレスのポート2001で動作し、まず接続してきたクライアントからデータ(文字列)を受信し、受信した文字列の長さを返信してから、クライアントを切断しています。

ちゃんと記事を読みましょう。

通常のコメント
NightShift 2019/05/3 (Fri) 16:40:31
分かりやすい記事をありがとうございます。
質問させていただきたいのですが、
以下のサーバ側の処理で、クライアント側から送られてきた文字列の長さをクライアント側へ送信している理由は何でしょうか。

if (!disconnected)
{
//クライアントにデータを送信する
//クライアントに送信する文字列を作成
string sendMsg = resMsg.Length.ToString();
//文字列をByte型配列に変換
byte[] sendBytes = enc.GetBytes(sendMsg + '\n');
//データを送信する
ns.Write(sendBytes, 0, sendBytes.Length);
Console.WriteLine(sendMsg);
}

通常のコメント
yamachok 2018/11/8 (Thu) 09:16:06
よく解りましたが、クローズのことで教えてください。クライアントが通信を終了したい時、TcpCleiant.closeでクローズしますが、その時VB6の時はサーバ側のソケットでクローズイベントが発生しておりました。VB.NETではこのイベントが発生しないためサーバ側が終了の処理が出来ず困っております。例にある通りテータのやり取りでクライアント側が終了する旨をデータで送る以外方法はないのでしょうか。

通常のコメント
管理人 2018/09/21 (Fri) 02:14:53
> 広告がすげー邪魔

現在は広告が自動で挿入される設定になっており、表示されるほとんどの広告は自動で挿入されたものです。そのため、これを制御することは難しいですが、もし具体的にこの広告が邪魔というものがございましたら、お知らせください。よろしくお願いいたします。

通常のコメント
匿名 2018/09/20 (Thu) 22:23:16
広告がすげー邪魔

評価の理由
評価の理由 2018/03/28 (Wed) 03:43:05
評価:良い
シンプルに必要な情報が詰め込まれていて素晴らしい

コピペで基本的な動作確認ができる完璧なサンプルがあり
コメントもわかり易く、改変の助けになります
いつもお世話になっております

評価の理由
hamada 2017/12/24 (Sun) 22:42:13
評価:良い
とても分かりやすい!
助かりました。

通常のコメント
Moo 2017/12/15 (Fri) 12:08:34
適度なコードの量と説明の量で素晴らしいです。
正確に安全に書けば長すぎて読みにくいし、はしょれば文句を言う人も出てくることでしょう。

理解しやすい手頃なバランスでコーディングされています。
すっと試せて毎度とても役に立っています。
有り難う御座います。

評価の理由
くぁ 2017/07/28 (Fri) 10:31:03
評価:良い
thanks

通常のコメント
パッケージC#er 2017/02/14 (Tue) 17:09:28
この記事ではないですが、
https://codezine.jp/article/detail/22
において「Socketはスレッドセーフではない」と書かれていますが、Socketはスレッドセーフです。MSDNにも書かれています。誤解を招くので訂正をお願いします。

通常のコメント
fio 2017/01/16 (Mon) 22:38:46
listener.Start()
でどんなIPアドレスにしてもエラーが発生します。

評価の理由
nagasaqa 2016/06/10 (Fri) 02:47:16
評価:良い
端的で判り安い 

通常のコメント
10代のおっさん 2015/11/6 (Fri) 21:21:16
>データの受信処理で
do~while (ns.DataAvailable)
の判定方法だと1.66MBの画像ファイルをbyte配列にして
転送しようとしたときに全部読み込まないうちに
ループを抜けてしまいました。

とありますが、画像などの比較的サイズの大きいものはUDPで通信することをお勧めします。本来TCPは大きなデータの送受信に向いておりません。
管理人ではないですが、返信コメントをさせていただきました。

通常のコメント
たすけ 2015/08/18 (Tue) 11:00:05
スレッドではないのですね。

通常のコメント
12gsu 2015/06/4 (Thu) 21:37:33
UIの方はどのように組めばよろしいのでしょうか。
まだ始めたばかりで詳しく分からないので、どうか回答おねがいします。

通常のコメント
管理人 2015/02/9 (Mon) 01:15:44
> 1.66MB全部読む前に途中で返ってきてしまいます。

説明不足の点が多々あり、申し訳ありません。次の機会に書き直したいと思います。ここで紹介している方法はかなり簡易的(手抜き?)ですので、大きなデータをやり取りする場合は、非同期で行った方がよいのではないかと思います。

通常のコメント
匿名 2015/02/4 (Wed) 01:00:06
Dobonさんのコードにはいつもお世話になっています

データの受信処理で
do~while (ns.DataAvailable)
の判定方法だと1.66MBの画像ファイルをbyte配列にして
転送しようとしたときに全部読み込まないうちに
ループを抜けてしまいました。
int resSize = ns.Read(resBytes, 0,resBytes.Length);
もresBytes.Length(1.66MB)分きっちり読んでくれるわけではないようでした。
1.66MB全部読む前に途中で返ってきてしまいます。
ので指定したbyte数分読むまでループするような処理に変更して対応しました。(一定時間たっても読めない場合はループを抜けるようにもしました)

評価の理由
匿名 2014/10/3 (Fri) 17:49:04
評価:良い
開発の参考にさせて頂きます

通常のコメント
匿名 2014/07/17 (Thu) 19:45:43
すみません。
全部把握していなかったようで、全部把握してみたら、切断が正しい事がよくわかりました。

通常のコメント
匿名 2014/07/17 (Thu) 19:29:07
サーバー側の処理で
> //Readが0を返した時はクライアントが切断したと判断
および
> Console.WriteLine("クライアントが切断しました。")
とありますが、
その後、サーバー側からクライアント側へ送信しているので、切断という表現はおかしいのでは?

本来の意味としては、「クライアントからの送信データをすべて受信した」という方が近いのかな?と思ったのですが、いかがでしょうか?

通常のコメント
管理人 2014/04/27 (Sun) 00:23:03
> ドメインをlocalhost以外の独自の物にできないですか?

もちろん可能です。

通常のコメント
nao20010128nao 2014/04/26 (Sat) 19:40:15
ドメインをlocalhost以外の独自の物にできないですか?

評価の理由
Moo 2014/02/21 (Fri) 18:48:06
評価:良い
簡潔なのに必要な事がしっかり書かれております。

通常のコメント
管理人 2013/08/1 (Thu) 00:33:02
何をしているのかよく分からないけれど、コピペすれば動くというサンプルが良いサンプルと言い切るのは難しいと思います。特にこのようなサーバーアプリケーションの場合、セキュリティの問題もありますので、なおさらではないでしょうか。このサンプルの場合、Listenするアドレスを表すIPAddressを指定するという点を明確にすべきで、IPAddress.Anyではその点が分かりにくくなります。しかも、意図していないアドレスをListenしてしまう可能性があります。さらに細かいことを言うと、IPAddress.Anyは万能ではなく、IPv4だけです。ですので、IPAddress.Anyを使用したサンプルが最善とは決して言い切れないと私は考えます。

通常のコメント
Bugtan 2013/07/31 (Wed) 16:07:32
MSDNのサンプルがそもそも良くないですね。
http://msdn.microsoft.com/ja-jp/library/c6z86e63%28VS.80%29.aspx
一応解説で補足説明されているとはいえ、Dns.Resolve("localhost").AddressList[0];を指定すべき状況なんてちょっと思いつかないです。
適当にコピペしてしまうと一見動く割に実は環境依存になっちゃう。

通常のコメント
管理人 2013/07/28 (Sun) 23:58:29
> TcpListenerコンストラクタに
> System.Net.Dns.GetHostEntry(host).AddressList[0];
> を渡しているのはサンプルとしては良くないかと。
>
> http://www.atmarkit.co.jp/fdotnet/special/networkprog/networkprog_03.html
> にあるようにIPAddress.Anyで良いと思います。

どちらの方がサンプルとして適切かは分かりませんので、両方の方法を併記することを検討します。ご提案、ありがとうございました。

通常のコメント
Bugtan 2013/07/18 (Thu) 11:46:23
TcpListenerコンストラクタに
System.Net.Dns.GetHostEntry(host).AddressList[0];
を渡しているのはサンプルとしては良くないかと。

http://www.atmarkit.co.jp/fdotnet/special/networkprog/networkprog_03.html
にあるようにIPAddress.Anyで良いと思います。

通常のコメント
管理人 2013/06/28 (Fri) 23:09:29
> TCPクライアントのソースで一点、returnしてしまうと
> 各種Closeされないのが気になりました。

遅ればせながら、修正させていただきます。ご指摘、ありがとうございました。

> MSDN の TcpClient.Close のヘルプには、「このメソッドを呼び出すと、関連する Socket が閉じられ、データが作成された場合の送受信に使用される、関連する NetworkStream も閉じられます。」とあり...
> MSDN ヘルプのドキュメントバグですかね?

「TcpClient.GetStream メソッド」の説明には「データの送受信を完了したときは、NetworkStream を終了する必要があります。 TcpClient を終了しても、NetworkStream は解放されません。」とありますので、私にも両者の説明は矛盾しているように思えます。

実際のところは、moveccrさんがご指摘のように、TcpClient.CloseでNetworkStreamも閉じられるようで、「TcpClient.Close メソッド」の説明が合っているようです。「TcpClient.GetStream メソッド」の説明の方が間違っている(もしくは別の意味なのかもしれませんが)ようです。

ただ、NetworkStreamも明示的に閉じた方が無難なので、このページのサンプルはこのままにしておきます。

ご指摘、ありがとうございました。

通常のコメント
moveccr 2013/04/10 (Wed) 11:38:38
MSDN の TcpClient.Close のヘルプには、
「このメソッドを呼び出すと、関連する Socket が閉じられ、データが作成された場合の送受信に使用される、関連する NetworkStream も閉じられます。」
とあり、実際 .Net4.0 の TCPClient.cs のソースを読んでも、 Close() Dispose() m_DataStream.Dispose() と呼び出しが行われ、
GetStream() で取得される m_DataStream の Dispose() がコールされているようです。
MSDN ヘルプのドキュメントバグですかね?

通常のコメント
覚醒通りすがり 2012/11/29 (Thu) 11:20:58
大変参考になりました。
TCPクライアントのソースで一点、returnしてしまうと
各種Closeされないのが気になりました。
↓ここ
if (resSize == 0)
{
Console.WriteLine("サーバーが切断しました。");
Console.ReadLine();
return;
}

通常のコメント
i-brown 2011/12/29 (Thu) 06:17:27
TCP/IPとUDP/IPのプログラムを作成するのに、大いに参考にさせていただきました。感謝しております! 同期メソッドから非同期メソッドに書き換え、スレッドプールの使用、サーバー側でリストによるコネクション管理、送信側は接続を保持させるなど手を入れていき、思うようなアプリケーションを作成できるようになりました。

通常のコメント
匿名 2011/06/14 (Tue) 17:13:17
ありがとうございます。

通常のコメント
管理人 2011/03/1 (Tue) 03:49:50
> System.IO.MemoryStream ms = new System.IO.MemoryStream();はCloseしていますが、
> System.Net.Sockets.NetworkStream ns = tcp.GetStream();はその処理がありません。

ご報告ありがとうございました。修正しておきます。

通常のコメント
匿名 2011/02/28 (Mon) 12:10:44
System.IO.MemoryStream ms = new System.IO.MemoryStream();はCloseしていますが、
System.Net.Sockets.NetworkStream ns = tcp.GetStream();はその処理がありません。

MSDNでは次のようになっています。
「データの送受信を完了したときは、 NetworkStream を終了する必要があります。 TcpClient を終了しても、 NetworkStream は解放されません」

評価の理由
なお 2011/01/25 (Tue) 01:21:05
評価:良い
ありがとうございます

評価の理由
納期前の職人 2010/11/20 (Sat) 16:41:16
評価:良い
ギリギリの状態で焦っている中、非常に参考になりました。
多謝です。

評価の理由
yoshism 2010/11/2 (Tue) 14:45:17
評価:良い
いつも参考にさせていただいてます。
感謝。

通常のコメント
easy 2010/04/22 (Thu) 16:17:33
とても参考になります。

評価の理由
ryks 2009/08/19 (Wed) 20:05:36
評価:良い
助かりました

評価の理由
味田村義和 2009/01/18 (Sun) 18:48:57
評価:良い
わかりやすい

通常のコメント
taka 2008/07/3 (Thu) 10:17:36
ドボンさんのような人がいるおかげで開発効率の向上や処理の理解にとても大きく影響を受けていると思います。
心から感謝します。

評価の理由
かっしー 2006/08/29 (Tue) 17:16:44
評価:良い
VB6.0ではWinsockがありましたが、.NET〜はその機能がなくなってしまって困っていたところ、大変参考になりました。ありがとうございます。

通常のコメント
hou 2006/04/26 (Wed) 10:26:03
わかりやすいけど
クライアント側切断されたのにサーバー側の
ns.Write(sendBytes, 0, sendBytes.Length);
を実行するとエラーはならないです
クライアント側の切断は判断できないですか?

評価の理由
nagasaka 2004/10/29 (Fri) 23:33:22
評価:良い
わかりやすい表示でした。

コメントの投稿

[説明]