個人問題發生環境:
1.TCP服務器是虛擬機,IP地址是192.168.8.12。
2.TCP客戶端是宿主機,IP地址是192.168.8.11。
3.從宿主機(192.168.8.11)上啟動Socket,發現無響應。
4.從服務器(192.168.8.12)上抓包,發現能抓到來自宿主機(192.168.8.11)的SYN消息。
5.然而服務器不響應SYN,ACK。
排查過程:
一、去網上找了找,可能的原因之一就是時間戳的問題。
1 當客戶端發出的syn包帶有時間戳的情況下,經過NAT轉換后,如果使用的端口被之前使用過,而且時間戳大於本次syn包中的時間戳。系統將會直接丟棄。造成本次鏈接無法正常完成TCP/IP的3次握手。 2 解決的方法很簡單,分為兩種: 3 在客戶端:關閉rfc1323 4 在服務端:設置sysctl.conf里面tcp_timestamps=0也可以只用命令sysctl -w net.ipv4.tcp_timestamps=0
嘗試了一下,在我的環境里解決不了問題。
二、找不到其他的原因了,由於之前我的客戶端是能夠成功連接服務器的。
我用了一個最直接的方法,重新寫了一個只連接的簡單的TCP客戶端鏈接例子。
奇怪的事情發生了,這個DEMO能鏈接成功!
三、步驟二是個好消息,我可以抓包對比了。
失望:所有的TCP設置參數都是一樣的。
繼續分析包的上層內容。
轉機:網絡層的MAC地址不一樣!
四、問題初步原因找到了。
虛擬機不回復SYN的原因是這個時候的包的目的地不是虛擬機,虛擬機起了個中轉作用。
目的地是哪兒呢?我掃描局域網內的機器,發現是我的網關地址。
五、進一步的原因?
為什么看起來同樣的代碼,卻導向了不同的網絡目的地,涉及網關,那就是跨網段路由了啊?
六、真相只有一個!
1 手動寫的Demo,服務器的地址是靜態的字符串“192.168.8.12”。 2 出問題的程序,我從配置文件里讀取的配置信息,而配置的地址是“192.168.1.12”(兩個開發環境的內網網段不一樣)。 3 簡單的總結原因就是【粗心】。