2011-01-30 37 views
2

我想通過監聽原始套接字通過代碼從網站讀取響應,但迄今爲止,我只能讀取由我的計算機發送的傳出請求,而不是我真正感興趣的即將到來的回覆。 我該如何去閱讀傳入的回覆?無法使用原始套接字讀取傳入響應

編輯:使用Wireshark我發現我正在尋找的數據正在通過TCP發送,我相信。

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Unspecified); 
IPAddress localIP = Dns.GetHostByName(Dns.GetHostName()).AddressList[0]; 
listener.Bind(new IPEndPoint(localIP, 0)); 
byte[] invalue = new byte[4] { 1, 0, 0, 0 }; 
byte[] outvalue = new byte[4] { 1, 0, 0, 0 }; 
listener.IOControl(IOControlCode.ReceiveAll, invalue, outvalue); 
while (true) 
{ 
    byte[] buffer = new byte[1000000]; 
    int read = listener.Receive(buffer); 
    if (read >= 20) 
    { 
     Console.WriteLine("Packet from {0} to {1}, protocol {2}, size {3}", 
      new IPAddress((long)BitConverter.ToUInt32(buffer, 12)), 
      new IPAddress((long)BitConverter.ToUInt32(buffer, 16)), 
      buffer[9], 
      buffer[2] << 8 | buffer[3] 
     ); 
    } 
} 
+0

新的IPEndPoint(localIP,0)指定您要偵聽端口0.是否是遠程服務器連接的端口? – 2011-01-30 03:35:43

+0

@RobertLevy - `new IPEndPoint(localIP,0)`指定你不關心你使用的是什麼本地端口。當(如果)你需要一個時,系統將選擇一個。 (綁定,發送,接收,...)對於設置了ReceiveAll的RAW套接字,您永遠不需要一個,因爲您正在接收所有內容。 – 2015-03-23 04:34:31

回答

4

端口0說,他將聽取所有端口上,我認爲你需要設置ProtocolType.Unspecified而不是ProtocolType.IP。

new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Raw); 是從我在msdn上讀取的ipv6中獲得的ProtocolType.IP支持帶有原始套接字的ipv4。

另外我認爲這是一個無連接套接字的權利? 回收不會真的有一個影響,除非是這種情況。

Socket sck = new Socket(AddressFamily.InterNetwork , SocketType.Raw , ProtocolType.IP); 
    sck.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true); 

希望這有助於:)

+0

在條件內我將字節數組轉換爲一個字符串,我已經能夠輕鬆地匹配Firebug中的Net選項卡。根據您提出的更改,我現在正在獲得一些傳入流量,儘管我的程序仍然沒有看到我在Firebug中看到的響應。我相信這是無連接的,儘管我昨天才開始研究套接字。 – CosworthTC 2011-01-30 15:00:20

1

我使用基本相同的原始套接字在我的C有類似的問題++程序: 如果您選擇的IP頭之後ü可以通過建立這樣的代碼得到它建立。就我而言,我可以在調試版本中看到傳入數據包,但不能在發佈版本中看到。在兩個版本中都可以看到傳出數據包。我沒有在這個程序中發送任何數據包。

我在Win7 x64下用VS2008原生C++編譯。

我的問題是與防火牆。當在VS中創建項目時,它顯然會在防火牆中爲項目構建的網絡訪問設置一個「允許」條目,但僅限於程序的調試版本。

我不得不爲發佈版本添加另一個條目,然後允許傳入數據包。 Win7下的高級防火牆設置也可能會導致特定的協議被阻止,所以如果您只收到部分收到的消息,請檢查您的程序條目的設置。

1

今天我想知道如何做同樣的事情!這裏是我的代碼現在似乎工作,因爲得到這個工作的功勞是由於同事回答「湯姆埃裏克」建議ProtocolType.IP。

static void Main(string[] args) 
    { 
     // Receive some arbitrary incoming IP traffic to an IPV4 address on your network adapter using the raw socket - requires admin privileges 
     Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); 
     IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList 
      .Where((addr) => addr.AddressFamily == AddressFamily.InterNetwork) 
      .Where((addr) => addr.GetAddressBytes()[0] != 127) 
      .First(); 
     s.Bind(new IPEndPoint(ipAddress, 0)); 
     byte[] b = new byte[2000]; 
     EndPoint sender = new IPEndPoint(0, 0); 
     int nr = s.ReceiveFrom(b, SocketFlags.None, ref sender); 
    }