TcpClientを半クロージングする際に重大な問題があります。私は何をしようとしていることである:半クローズTcpClient
クライアント上:
- メッセージ
- シャットダウンを送る
- を送信するための基盤となるソケットは(
- シャットダウンに読み取るための基本となるソケットを応答を受け取りますまたは、この時点で閉じてください)
サーバー上:
- は
- を読み取るための基盤となるソケットは、しかし(ただそれを閉じ、この時点で、または)
- シャットダウンに
を記述するための基盤となるソケットを応答を送信メッセージ
//initialize the connection between the server and the client
var listener = new TcpListener(IPAddress.Any, 13546);
listener.Start();
var client = new TcpClient("127.0.0.1", 13546);
var server = listener.AcceptTcpClient();
listener.Stop();
//CLIENT: send the message
var cwriter = new StreamWriter(client.GetStream());
cwriter.Write("client's message");
cwriter.Flush();
client.Client.Shutdown(SocketShutdown.Send);
//SERVER: receive the message
string msg;
var sreader = new StreamReader(server.GetStream());
msg = sreader.ReadToEnd();
server.Client.Shutdown(SocketShutdown.Receive);
//SERVER: send a response
//Here the code fails on server.GetStream() -
//InvalidOperationException, apparently the whole connection is closed now
var swriter = new StreamWriter(server.GetStream());
swriter.Write(msg + " with server's response");
swriter.Flush();
server.Client.Shutdown(SocketShutdown.Send);
//CLIENT: receive the message
var creader = new StreamReader(client.GetStream());
var response = creader.ReadToEnd();
client.Client.Shutdown(SocketShutdown.Receive);
はrawソケットを使用せずにこれを実行する方法はあります?私が間違っていることはありますか?
フェイルとは何ですか?生のソケットへの飛び越しは時期尚早で恣意的なようです。むしろ、バグを修正して、あなたは良いです。 – usr
'StreamWriter'は、渡されたストリームの所有権を取得します。ガーベジコレクションされると、下にあるストリームも同様に廃棄されます。 'StreamWriter'を廃棄した場合、これは明らかに分かります(あなたは' IDisposable'で何をしているのでしょうか?)。ストリームを開いたままにするコンストラクタのオーバーロードを使用できます。あるいは、これを気にしないでください。 'TcpClient'の基底のソケットにアクセスする必要がある場合、通常は間違っています。正しいアボートロジックで手動でソケットをシャットダウンする必要はありません。 –
@ JeroenMostert良いキャッチですが、問題は簡単には現れません。 SRにはファイナライザもありますか?それはしないでください。また、シャットダウンすることでストリームの完了をリモート側に知らせることができます。私は受信をシャットダウンすることはあまりありませんね、はい。 – usr