
2개의 네트워크 인터페이스가 있는 Windows 10 PC가 있습니다. 이러한 인터페이스 중 하나는 파일 서버, DNS 및 인터넷용 라우터가 있는 기본 LAN으로 연결됩니다. 두 번째 인터페이스는 PLC와 HMI가 있는 작은 LAN입니다. 둘 다 물리적으로 동일한 LAN에 있지만 다른 서브넷에 있습니다(죄송합니다. 내 통제 범위 밖에서는 변경할 수 없습니다).
따라서 두 개의 물리적 인터페이스와 하나의 논리적 인터페이스가 있습니다. eth0: DHCP, 172.16.xy, MASK 255.255.255.0, 기본 gw 172.16.xz eth1: static 192.168.1.158, MASK 255.255.255.0 static 192.168.19.158, MASK 255.255. 255.0
HMI는 192.168.19.135에서 연결할 수 있습니다.
이제 HMI를 재부팅하면 다시 연결할 수 있는지 확인하기 위해 ping을 시작합니다. 이는 약 30초 후에 발생합니다. 하지만 80~90년대 이후에만 긍정적인 핑 응답을 받았습니다.
Ping wird ausgeführt für 192.168.19.135 mit 32 Bytes Daten:
Antwort von 192.168.19.158: Zielhost nicht erreichbar.
Zeitüberschreitung der Anforderung.
Zeitüberschreitung der Anforderung.
Zeitüberschreitung der Anforderung.
(독일어 텍스트로 인해 죄송하지만 여기서 보는 내용은 여전히 명확해야 한다고 생각합니다.) 두 번째 핑이 아닌 첫 번째 핑에 대해 또 다른 응답을 받았습니다.
XP 이후의 Windows는 "라우팅 마법"을 수행하기 시작했으며 더 구체적인 경로에서 대상에 도달할 수 없는 경우 기본 경로로 데이터를 전송하기 시작한 것 같습니다. 다른 사람들도 그랬던 것 같아이 문제
나에게 실제 솔루션이 아닌 몇 가지 "솔루션"을 찾았습니다(자세한 내용은 아래 참조).
- 따라서 ping에는 소스 주소를 정의하는 멋진 "-S" 매개변수가 있습니다. 그리고 그렇습니다. 이것이 문제를 "해결"합니다. HMI가 작동 중이면 즉시 응답을 받습니다. 하지만 저는 powershell-script에서 해당 명령을 사용하고 있으며 "test-connection"에 대한 소스 매개 변수는 완전히 다른 의미를 갖습니다. 그리고 이것을 스크립트에서 사용하기 때문에 로컬 IP가 변경되자마자 실패합니다.
- DHCP 대신 정적으로 eth0을 구성했으며 기본 경로를 정의하지 않았습니다. 이것은 또한 문제를 "해결"했습니다. (이것이 실제로 해결책이 아닌 이유를 상상할 수 있을 것 같습니다.)
- 나는 이것을 이론적으로만 조사했지만 PLC와 HMI를 사용하여 PC, LAN 및 격리된 LAN 사이에 3개의 인터페이스가 있는 Linux 기반 라우터를 설치하고 모든 라우팅을 수행하도록 할 수 있습니다(이렇게 하면 확실히 문제가 해결됩니다! 하지만 솔직히 깨진 창 라우팅을 해결하려면 추가 컴퓨터가 필요합니까?)
- 'arp -d *'도 도움이 되는 것 같지만 높은 권한이 필요합니다.
다양한 매개변수와 측정항목을 사용하여 정적 경로를 추가해 보았습니다. 변경 없음! HMI의 MAC를 정적으로 추가하는 것은 이 MAC이 변경될 수 있으므로 도움이 되지 않습니다.
그래서 내 질문은 다음과 같습니다
- Windows의 이러한 동작 변경에 대한 문서가 있습니까?
- 창에서 정의된 인터페이스를 사용하도록 강제하는 방법이 있나요?
답변1
그래서 쉬운 해결책을 찾지 못한 후 저는 Microsoft가 Windows에서 라우팅을 심하게 엉망으로 만들어 발생한 문제를 해결하기 위해 프로그래밍하기로 결정했습니다.
powershell의 cmdlet 테스트 연결 대신 -S 매개변수와 함께 클래식 핑을 사용하고 있습니다.
내 코드의 ping 부분은 이제 다음과 같습니다.
$localIPs = (Get-NetIPConfiguration -InterfaceAlias "PLC").IPv4Address.IPAddress
# because this command returns a string, when the interface has a single IP-address but an array of strings if the interface has more than one address, we need to check for this
if ($localIPs.GetType().Name -eq "string") { # only a single IP
$localIP = $localIPs
}
else { # more than one IP
$localIP = $localIPs[0] # since it seems that windows does use the ip address as a synonym for the interface, it's not important which of the addresses of that interface we use. So we're just picking the first one
}
$pingcount = 180
do {
ping $HMI4IP -n 1 -w 1000 -S $localIP | Out-Null # redirect the output of ping to /dev/null
$pingreply = $?
$pingcount = $pingcount - 1
}
until ($pingcount -eq '0' -or $pingreply)
if ($pingreply) {
# code here
}
else {
exit 1337 # return with an error code, we've not reached our target
}
이를 위해서는 PLC와 HMI가 연결된 인터페이스의 이름이 "PLC"인지 확인하면 됩니다. 주소를 문자열이나 주소 배열(인터페이스에 하나 이상의 주소가 있는지 여부에 따라 다름)로 가져오고 처리해야 합니다(동적 입력에 오신 것을 환영합니다...). 이 데이터를 ping에 입력하는 것만큼 쉽습니다(Test-Connection은 자신의 이익을 위해 너무 똑똑하려고 하기 때문입니다). $로? 마지막 명령이 성공을 반환했다는 사실을 확인하고, 실패했다면 거짓을 반환했습니다. 그러면 그 이후부터는 처리하기가 쉽습니다.
내가 아는 한, 이 동작과 이를 처리하는 방법에 대한 Microsoft의 문서는 없습니다. 이는 매우 슬픈 일이라고 생각합니다.