2012-08-08 17 views
12

ソケットを使用してHTTP requestを作成しようとしています。次のように私のコードは次のとおりです。私は上記のコードを実行したときに、私は、ブラウザで私のrequest_urlを入力したとき、私はApplication Registeredことを、私は、ブラウザからの取得応答がC#:ソケットを使用してHTTPリクエストを実行するには?

であると言ってうなりから通知を得るのに対し、

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
class test 
{ 
    public static void Main(String[] args) 
    { 
     string hostName = "127.0.0.1"; 
     int hostPort = 9887; 
     int response = 0; 

     IPAddress host = IPAddress.Parse(hostName); 
     IPEndPoint hostep = new IPEndPoint(host, hostPort); 
     Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

     sock.Connect(hostep); 

     string request_url = "http://127.0.0.1/register?id=application/vnd-fullphat.test&title=My%20Test%20App"; 
     response = sock.Send(Encoding.UTF8.GetBytes(request_url)); 
     response = sock.Send(Encoding.UTF8.GetBytes("\r\n")); 

     bytes = sock.Receive(bytesReceived, bytesReceived.Length, 0); 
     page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes); 
     Console.WriteLine(page); 
     sock.Close(); 
    } 
} 

は今、何も起こりません

SNP/2.0/0/OK/556 

私のコードから得た回答はSNP/3.0/107/BadPacketです。

私のコードで何が問題になっていますか。

Snarl Request format specification

+1

「System.Net.Http.HttpClient」ではなく、ソケットを使用する必要がある理由はありますか?そのために –

+2

またはWebclient ... – steveg89

+0

いいえ具体的な理由はありません。実際には、私はHttpCLientまたはWebclientを認識していませんでした。しかし、とにかく、私は上記のコードで狼狽を理解したいと思う。 – RanRag

答えて

7

あなたは、ヘッダーの終わりを示すために、最終的には、コンテンツの長さと重改行を含める必要があります。

var request = "GET /register?id=application/vnd-fullphat.test&title=My%20Test%20App HTTP/1.1\r\n" + 
    "Host: 127.0.0.1\r\n" + 
    "Content-Length: 0\r\n" + 
    "\r\n"; 

HTTP 1.1仕様では、ここで見つけることができます:http://www.w3.org/Protocols/rfc2616/rfc2616.html

+0

ありがとう。ちょうど私が探していたもの。 – kurt

1

あなたの要求が正しくありません。 wikipedia, a HTTP Get requestによるように見えるように持っている:

string request = "GET /register?id=application/vnd-fullphat.test&title=My%20Test%20App HTTP/1.1\r\nHost: 127.0.0.1\r\n"; 
+0

私はまだ 'SNP/3.0/107/BadPacket'を取得しています – RanRag

+3

あなたの要求には、Connection、Accept、Accept-Encodingなど何かが必要なようです。 PVittが示したものは最小の要求ですが、それはあなたの特定のプロトコルでは十分ではないかもしれません。上記のようにWebClientを使って作業してみて、そのAPIがうまく動作することを確認してください。 –

+0

受け入れられた答えによると、それは 'Content-Length'だったはずです。 – vapcguy

13

私は、SNPについて何も知りません。あなたのコードは受信側で少し混乱しています。私はHTTP GET要求のためのサーバレスポンスを送信して読むために、この例を使っています。最初にリクエストを見てから、レスポンスを調べてみましょう。我々はすでに指定されている、それは、正確に202バイトである知っているので、私は意図的に、サーバの応答の本体をommitedいる

HTTP/1.1 200 OK 
Date: Sun, 07 Jul 2013 17:13:10 GMT 
Server: Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.16 
Last-Modified: Sat, 30 Mar 2013 11:28:59 GMT 
ETag: \"ca-4d922b19fd4c0\" 
Accept-Ranges: bytes 
Content-Length: 202 
Keep-Alive: timeout=5, max=100 
Connection: Keep-Alive 
Content-Type: text/html 

string - "HTTP/1.1 200 OK\r\nDate: Sun, 07 Jul 2013 17:13:10 GMT\r\nServer: Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.16\r\nLast-Modified: Sat, 30 Mar 2013 11:28:59 GMT\r\nETag: \"ca-4d922b19fd4c0\"\r\nAccept-Ranges: bytes\r\nContent-Length: 202\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n" 

GET/HTTP/1.1 
Host: 127.0.0.1 
Connection: keep-alive 
Accept: text/html 
User-Agent: CSharpTests 

string - "GET/HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nAccept: text/html\r\nUser-Agent: CSharpTests\r\n\r\n" 

ServerのHTTPレスポンスヘッダ:

HTTP GETリクエスト

レスポンスヘッダーのContent-Lengthで指定します。

HTTP仕様を調べると、HTTPヘッダーが空の改行( "\ r \ n \ r \ n")で終わることがわかります。だから我々はそれを検索する必要があります。

実際のコードを見てみましょう。 System.Net.Sockets.Socket型の可変ソケットを想定します。

socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
socket.Connect("127.0.0.1", 80); 
string GETrequest = "GET/HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nAccept: text/html\r\nUser-Agent: CSharpTests\r\n\r\n"; 
socket.Send(Encoding.ASCII.GetBytes(GETrequest)); 

私たちはサーバーに要求を送りました。応答を受け取り、正しく解析しましょう。

bool flag = true; // just so we know we are still reading 
string headerString = ""; // to store header information 
int contentLength = 0; // the body length 
byte[] bodyBuff = new byte[0]; // to later hold the body content 
while (flag) 
{ 
// read the header byte by byte, until \r\n\r\n 
byte[] buffer = new byte[1]; 
socket.Receive(buffer, 0, 1, 0); 
headerString += Encoding.ASCII.GetString(buffer); 
if (headerString.Contains("\r\n\r\n")) 
{ 
    // header is received, parsing content length 
    // I use regular expressions, but any other method you can think of is ok 
    Regex reg = new Regex("\\\r\nContent-Length: (.*?)\\\r\n"); 
    Match m = reg.Match(headerString); 
    contentLength = int.Parse(m.Groups[1].ToString()); 
    flag = false; 
    // read the body 
    bodyBuff = new byte[contentLength]; 
    socket.Receive(bodyBuff, 0, contentLength, 0); 
} 
} 
Console.WriteLine("Server Response :"); 
string body = Encoding.ASCII.GetString(bodyBuff); 
Console.WriteLine(body); 
socket.Close(); 

これはおそらくC#でこれを行うには最悪の方法であり、.NETでHTTPリクエストとレスポンスを処理するためのクラスのトンがありますが、あなたがそれを必要に応じて、まだ、それが動作します。

0

HTTP要求の最小要件は、 "GET/HTTP/1.0 \ r \ n \ r \ n"です(ホストの削除が許可されている場合)。 しかし、SNARLでは、コンテンツの長さ(私が一番聞いたもの)を入力する必要があります。

ので、

 Socket sck = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp); 

     sck.Connect(ip, port); 
     sck.Send(Encoding.UTF8.GetBytes("THE HTTP REQUEST HEADER")); 
     Console.WriteLine("SENT"); 
     string message = null; 
     byte[] bytesStored = new byte[ReceiveBufferSize]; 
     int k1 = sck.Receive(bytesStored); 
     for (int i = 0; i < k1; i++) 
     { 
      message = message + Convert.ToChar(bytesStored[i]).ToString(); 
     } 
     Console.WriteLine(message); // PRINT THE RESPONSE 

編集:私は、以前の貧しい答えを深く申し訳ありません。それは非形式化されており、私は答えの主なアイデア/解決策を追加しました(直接的な情報はありません)。さらに、私はソースコードを追加しました。

私はいくつかのサイトでテストし、それは完全に動作します。それがうまくいかなかった場合は、ヘッダーを追加して修正する必要があります(可能性が高いソリューション)。

関連する問題