2017-12-15 3 views
0

우선이 중요한 서버에 대해 언급하지 않으면이 전용 서버가 없습니다. 하지만 서버의 IP에 대해 알고 있습니다. 그래서 문제는 클라이언트가 그 IP에 연결하는 경우입니다, 어떻게 그것을 사용하는 클라이언트 IP를 알 수 있습니까? 클라이언트는 둘 이상의 네트워크 어댑터를 가질 수 있기 때문에 각각 하나가 다른 네트워크에 연결됩니다. 또한 서버는 클라이언트와 동일한 LAN에있을 필요가 없으며 클라이언트의 패킷이 서버에 도달하기 전에 여러 번 홉을 요구할 수 있습니다. 우리는 서버의 IP를 알고 있습니다.이 경우 클라이언트의 IP를 어떻게 알 수 있습니까?일부 대상 IP에 연결하는 데 사용되는 클라이언트 IP를 가져 옵니까?

전용 서버가 없기 때문에 일부 서버 응용 프로그램 (일부 클라이언트 관리자)을 통해 클라이언트의 IP를 감지 할 수 없습니다. 또한 Ping 클래스는이 경우 도움이되지 않는 것으로 보입니다. 또한 일반적으로 서버에서 Ping을 사용할 필요가 없습니다. 현재 서버는 클라이언트가 일부 쿼리를 직접 실행하는 SQL Server입니다. SQL Server에 대한 쿼리를 실행할 때 (sys.dm_exec_connections 사용) 클라이언트의 IP를 얻을 수 있지만 최후의 수단 일뿐입니다. 클라이언트에서 직접 다른 방법을 찾고 싶습니다 (SQL Server를 사용하지 않고).

내가 따라갈 수있는 가장 가까운 접근법은 다음과 같습니다. 그러나 왜 이것이 마지막 주소를 선택했는지 정말로 모르겠습니다.

var hn = System.Net.Dns.GetHostName(); 
var ipEntry = System.Net.Dns.GetHostEntry(hn); 
IPAddress[] addr = ipEntry.AddressList; 
var ip = addr[addr.Length - 1].ToString();//why the last? 

어떤 방법은 AddressList에 포함되지 않은 (직접적으로 동일한 LAN에) 많은 IP 주소가 있습니다.

제 문제는 클라이언트 (클라이언트에서 사용 가능한 네트워크 어댑터에서 시작)와 서버 (미리 알려진 IP) 사이에 가능한 모든 네트워크 경로를 찾는 것입니다. 거의 모든 경우에 사용할 수있는 경로가 1 개만 있어야합니다 (따라서 고객의 IP를 하나만 찾아야합니다). 클라이언트에서 일부 요청을 보내려고하면 경로를 찾아야하지만 현재 수행 방법에 대한 단서가 없습니다.

문제를 충분히 설명했으면 좋겠습니다. 당신의 도움을 주셔서 감사합니다!

+0

당신은 단지에 대한 클라이언트 [tracert와 (https://stackoverflow.com/questions/142614/traceroute-and-ping-를 얻을 수 있습니다 in-c-sharp) 그런 다음 해당 정보를 서버로 보냅니 까? 또는 SQL 인 경우 데이터베이스에 기록하십시오. – john

+1

서버가 있는지 여부와이 모든 것이 왜 필요한지 아직 이해하지 못했습니다. 어쨌든, NetworkInterface.GetAllNetworkInterfaces를 보시오. – Evk

+0

@Evk 내가 직접 연결된 클라이언트를 관리 할 수 ​​있도록 내 자신의 앱이 서버에서 실행되지 않는다는 것을 의미한다. 네트워크 인터페이스에는 클라이언트가 일부 대상으로 라우팅 할 수있는 모든 가능한 IP가 있습니다.이 경우 사용해야하는 정확한 IP를 알고 싶습니다 (거의 모든 경우에 하나의 IP와 하나의 경로가 있어야합니다. 클라이언트에서 대상으로). – Hopeless

답변

0

서버 쪽에서 사용할 수있는 수신 포트 (HTTP 포트, SSH 포트 또는 SQL Server 포트)를 사용하여 클라이언트 측에서 쉽게이 작업을 수행 할 수 있습니다. 여기에 작은 파이썬 프로그램입니다 :

import sys 
import socket 
if len(sys.argv) != 3: 
    print("Usage: {} ip-or-hostname port-number".format(sys.argv[0])) 
    sys.exit(1) 
hostname = sys.argv[1] 
port = int(sys.argv[2]) 
s = socket.socket() 
s.connect((hostname, port)) 
print(s.getsockname()[0]) 

그것이 무엇을하는 대상 시스템에 대한 연결을 만드는 것입니다, 그때 연결에 사용되는 지역 주소를 제공하는 getsockname 시스템 호출을 사용합니다. 이 로컬 주소는 항상 클라이언트 측 인터페이스 중 하나에 해당합니다. 내가 인수 www.google.com 80 그것을 실행하는 경우

그래서 예를 들어, 내가 얻을 :

python /tmp/disc.py www.google.com 80 
192.168.0.110 

내가 대신 다른 로컬 서브넷에 그것을 기계의 주소와 포트를 제공하면, 내가 얻을 :

반환 된 두 개의 주소

python /tmp/disc.py 192.168.40.128 22 
192.168.40.131 
내 로컬 시스템에 두 개의 서로 다른 인터페이스에 해당합니다

ip -4 addr 
[snipped] 
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 
    inet 192.168.0.110/24 brd 192.168.0.255 scope global dynamic ens33 
     valid_lft 166968sec preferred_lft 166968sec 
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 
    inet 192.168.40.131/24 brd 192.168.40.255 scope global ens34 
     valid_lft forever preferred_lft forever 
,

C#에서 동일한 프로그램을 쉽게 구현할 수있을 것이라고 확신합니다. 친숙한 언어가 아닙니다.

+0

내 서버가 SQL 웹 서버 인 HTTP 웹 서버를 호스트하지 않습니다.이 서버를이 서버에 적용 할 수 있습니까? 내가 제공 한 코드가 C# 인 경우 직접 시도 할 수 있습니다. – Hopeless

+0

C# 버전에 대한 내 대답을 참조하십시오, 당신의 대답은 실제로이 문제를 해결할 수있는 아이디어를 제기하는 소스입니다. 그래서 나는이 대답을 받아 들였지만,이 문제에 대한 해결책을 찾는 사람들은 (C#을 사용하여) 제 대답을 대신보십시오. – Hopeless

0

클라이언트 (우리는 HttpClient, WebClient를 가지고 있습니다 ...하지만이 경우에는 TcpClient이 필요합니다) 역할을하는 하나의 중요한 이미 내장 된 클래스를 놓친 것처럼 보입니다.일부 IP (일부 포트 제공)에 연결을 시도 할 수 있으며 성공하면 해결 된 LocalEndPoint의 기본 webSocket을 얻을 수 있습니다. 그것은 단지 문자열로 변환 될 수 있지만 사용 된 클라이언트 IP (문자열 형식은 IP:port과 같습니다)에 대해 구문 분석 할 수 있습니다. 여기에 몇 줄의 코드는 내가 원하는 것을 달성하는 것입니다 :

확실히
public string GetIPConnectingTo(string targetIP, int port = 80){ 
    try { 
     using(var tc = new TcpClient(targetIP, port)){ 
      return tc.Client.LocalEndPoint.ToString().Split(':')[0]; 
     } 
    } 
    catch { 
     return null; 
    } 
} 
관련 문제