访问一个网站,从本地访问很快,可是从客户端访问大概要等待3秒的样子。在服务器放上静态网页,在客户端访问则返回时间很快。web
在客户端访问问题网站,在客户端用wireshark抓包shell
让开发人员调查服务器端的应用,开发人员说以前有个小功能能够抓取客户端MAC地址,可是看到抓的包,应该不是用的客户端的代码,由于第一个web页响应就3秒多,要是客户端代码那也是后续的JS或者资源加载较慢。c#
开发人员给了我服务器端的代码C#
``` c#
[DllImport("Iphlpapi.dll")]
private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);
[DllImport("Ws2_32.dll")]
private static extern Int32 inet_addr(string ip);api
public string getClientMac(string userip) { if (string.IsNullOrEmpty(userip)) return null; //string userip = Request.UserHostAddress; string strClientIP = userip.ToString().Trim(); Int32 ldest = inet_addr(strClientIP); Int32 lhost = inet_addr(""); Int64 macinfo = new Int64(); Int32 len = 6; int res = SendARP(ldest, 0, ref macinfo, ref len); string mac_src = macinfo.ToString("X"); //if (mac_src == "0") //{ // ip = userip; //} while (mac_src.Length < 12) { mac_src = mac_src.Insert(0, "0"); } string mac_dest = ""; for (int i = 0; i < 11; i++) { if (0 == (i % 2)) { if (i == 10) { mac_dest = mac_dest.Insert(0, mac_src.Substring(i, 2)); } else { mac_dest = "-" + mac_dest.Insert(0, mac_src.Substring(i, 2)); } } } return mac_dest; }
* 按照代码逻辑的话,服务器应该是用了一次SendARP 调用,可是为何会有三个ARP请求产生,并且不一样的ARP请求包之间的等待时间不一。因此为了验证这个SendARP的调用的实际操做,我用powershell 写了上面一个sendARP 调用,而后用wireshark抓包。 ``` powershell Function Send-Arp { param( [string]$DstIpAddress, [string]$SrcIpAddress = 0 ) $signature = @" [DllImport("iphlpapi.dll", ExactSpelling=true)] public static extern int SendARP( uint DestIP, uint SrcIP, byte[] pMacAddr, ref int PhyAddrLen); "@ Add-Type -MemberDefinition $signature -Name Utils -Namespace Network try { $DstIp = [System.Net.IPAddress]::Parse($DstIpAddress) $DstIp = [System.BitConverter]::ToInt32($DstIp.GetAddressBytes(), 0) } catch { Write-Error "Could not convert $($DstIpAddress) to an IpAddress type. Please verify your value is in the proper format and try again." break } if ($SrcIpAddress -ne 0) { try { $SrcIp = [System.Net.IPAddress]::Parse($SrcIpAddress) $SrcIp = [System.BitConverter]::ToInt32($SrcIp.GetAddressBytes(), 0) } catch { Write-Error "Could not convert $($SrcIpAddress) to an IpAddress type. Please verify your value is in the proper format and try again." break } } else { $SrcIp = $SrcIpAddress } $New = New-Object PSObject -Property @{ IpAddress = $DstIpAddress PhysicalAddress = '' Description = '' ArpSuccess = $true } | Select-Object IpAddress,PhysicalAddress,ArpSuccess,Description $MacAddress = New-Object Byte[] 6 $MacAddressLength = [uint32]$MacAddress.Length $Ret = [Network.Utils]::SendARP($DstIp, $SrcIp, $MacAddress, [ref]$MacAddressLength) if ($Ret -ne 0) { $New.Description = "An error was returned from SendArp() with error code: $($Ret)" $New.ArpSuccess = $false } else { $MacFinal = @() foreach ($b in $MacAddress) { $MacFinal += $b.ToString('X2') } $New.PhysicalAddress = ($MacFinal -join ':') } Write-Output $New }
使用powershell 来解析一个跨网段的目标IP地址,而后紧接着ping目标主机,这样能够根据ping包的开始时间得出sendARP 的结束时间。
powershell 命令以下:服务器
send-arp serverIP ;ping serverIP
在服务器上本机访问很是快,是由于服务器使用ARP请求查本机,应该会很快有回应。若是其余客户端和服务器在同一个网段,估计也不会慢。网络
客户端慢是由于服务器在返回给客户端http信息时,先用ARP请求跨网段的客户端IP,可是不会有ARP回应,由于路由的缘由,客户端看不到服务器的ARP请求,而SendARP函数的超时时间大概为3.1秒,因此跨网段的客户端收到服务器的一个HTTP响应在3.28秒左右。一样单纯在客户端抓包只能分析出服务器应用有问题,可是说不出具体的问题。tcp
静态网页快是由于,静态网页不执行服务器端代码,因此不会执行ARP查询。ide