私は、互いに通信するために手作業で書かれたHTTP要求を使用するTCPクライアントとサーバーをC#で作成しています。私が持っている問題は、を使ってNetwork Stream
から読むことです。これまでのところ、私は多くの方法を試しましたが、無駄です。StreamReaderでHTTP要求を読み取る
私のTCPクライアントからのリクエストは様々な形であります。
HTTP 1.0:
"POST /" +名+ "HTTP/1.0のデータベースを更新するために、要求は次のようになり(CRLFは私が
"\r\n"
文字列を表すために使用する定数です) "+ CRLF +" Content-Length: "+ length + CRLF + CRLF + location;
HTTP 1.1:
"POST/HTTP/1.1" + CRLF +ホスト名+ "のContent-Length:" +長さ+ CRLF + CRLF + nameLocString。
要求は正しい形式であり、クライアントは正しく送信しています。私は、問題なく問題に応答したアクセス権を持っているサーバーでこれをテストしました。
私の問題はTCPリスナーコードにあります。コード全体を投稿しないようにするには、問題のあるコードの部分だけを含めます(デバッグによって見つけ出した部分)。
Serverコード:
NetworkStream socketStream = new NetworkStream(connection);
StreamReader sr = new StreamReader(socketStream);
string input = ReadAllLinesWithNull(sr); // reading version 1
string input = ReadAllLinesWithEndOfStream(sr); // reading version 2
string input = ReadAllLinesWithPeek(sr); // reading version 3
string input = sr.ReadToEnd(); // reading version 4
、使用方法は以下のとおりです。読書のためのこれらのメソッドの
static string ReadAllLinesWithNull(StreamReader sr)
{
string input;
string nextLine;
input = sr.ReadLine();
while ((nextLine = sr.ReadLine()) != null)
{
Console.WriteLine(input);
input += nextLine;
}
sr.Close();
return input;
}
static string ReadAllLinesWithEndOfStream(StreamReader sr)
{
string input = "";
while (!sr.EndOfStream)
{
input += sr.ReadLine();
}
sr.Close();
return input;
}
static string ReadAllLinesWithPeek(StreamReader sr)
{
string input = "";
while (sr.Peek() >= 0)
{
input += sr.ReadLine();
}
sr.Close();
return input;
}
どれも働きました。接続タイムアウトが設定されていると、入出力の例外が発生しているので、接続が強制的に終了するまでに時間がかかっていました。私はタイムアウトをオフにし、Readには不確定な時間がかかりました。私はそれが最終的に2つのCRLF("\r\n\r\n"
)のクラスタがある場合に、ストリームリーダーは対処できないことが判明プロトコルとのすべてのバージョンでハング場所を選び出すことができたReadLine()
Sを使用する
感謝これと一緒に立ち往生する。
これを回避する方法についてご意見はありますか?仕様にあるように、複数のCRLFを含むバージョンを使用する必要があります。
追加情報が必要な場合は、可能な限りssonとして提供するようにします。
「これに対処できずに立ち往生できません」というコードを投稿することはできますか? 'ReadLine'には終端のリターンや改行は含まれていないことに注意してください(https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline%28v=vs.110%29.aspx) 、あなたが投稿したものは、リターンと改行を取り除いて連結されたすべてのコンテンツを返します。 –
@DourHighArch私が提供したコードは、すべてが失敗しているコードです。私はチェックし、クライアントは正しくストリームに記載されているHTTP要求を書き込み、それらをフラッシュし、私はReadLineメソッドのいずれかを使用して読むと、Content-Length:+ length + CRLF + CRLFを超えたものは得られません。タイムアウトが設定されていると、無期限に読み込まれるか、例外がスローされます。 ReadLineについてのご注意ありがとうございます。最初はできるだけシンプルに読んで、後で正しい読みを見たいと思っていました。私は新しい単純なサーバー(ちょうど読んでエコー)で読書をテストし、それは同じ問題を抱えていた。 –