访问一个网站,从本地访问很快,但是从客户端访问大概要等待3秒的样子。在服务器放上静态网页,在客户端访问则返回时间很快。
创新互联建站是创新、创意、研发型一体的综合型网站建设公司,自成立以来公司不断探索创新,始终坚持为客户提供满意周到的服务,在本地打下了良好的口碑,在过去的十多年时间我们累计服务了上千家以及全国政企客户,如成都LED显示屏等企业单位,完善的项目管理流程,严格把控项目进度与质量监控加上过硬的技术实力获得客户的一致赞美。在客户端访问问题网站,在客户端用wireshark抓包
让开发人员调查服务器端的应用,开发人员说之前有个小功能可以抓取客户端MAC地址,但是看到抓的包,应该不是用的客户端的代码,因为第一个web页响应就3秒多,要是客户端代码那也是后续的JS或者资源加载较慢。
开发人员给了我服务器端的代码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);
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秒左右。同样单纯在客户端抓包只能分析出服务器应用有问题,但是说不出具体的问题。
静态网页快是因为,静态网页不执行服务器端代码,所以不会执行ARP查询。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。