문제

나는 알아내야 해 외부 C# 애플리케이션이 실행 중인 컴퓨터의 IP입니다.

응용 프로그램에서 .NET Remoting을 통해 서버에 연결되어 있습니다.서버 측에서 클라이언트 주소를 얻는 좋은 방법이 있습니까?

(좀 더 명확하게 질문을 편집했습니다.질문에 답변하기 위해 최선을 다한 모든 친절한 분들께 사과드립니다. 아마도 제가 조금 모호했을 수도 있습니다.)

해결책:
나에게 딱 맞는 방법을 찾았어요.CommonTransportKeys.IPAddress에 액세스할 수 있는 사용자 지정 IServerChannelSinkProvider 및 IServerChannelSink를 구현하면 CallContext에 클라이언트 IP를 쉽게 추가할 수 있습니다.

public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, 
    IMessage requestmessage, ITransportHeaders requestHeaders, 
    System.IO.Stream requestStream, out IMessage responseMessage, 
    out ITransportHeaders responseHeaders, out System.IO.Stream responseStream)
{
    try
    {
        // Get the IP address and add it to the call context.
        IPAddress ipAddr = (IPAddress)requestHeaders[CommonTransportKeys.IPAddress];
        CallContext.SetData("ClientIP", ipAddr);
    }
    catch (Exception)
    {
    }

    sinkStack.Push(this, null);
    ServerProcessing srvProc = _NextSink.ProcessMessage(sinkStack, requestmessage, requestHeaders,
        requestStream, out responseMessage, out responseHeaders, out responseStream);

    return srvProc;
}

그런 다음 나중에(클라이언트로부터 요청을 받으면) 이렇게 CallContext에서 IP를 가져옵니다.

public string GetClientIP()
{
    // Get the client IP from the call context.
    object data = CallContext.GetData("ClientIP");

    // If the data is null or not a string, then return an empty string.
    if (data == null || !(data is IPAddress))
        return string.Empty;

    // Return the data as a string.
    return ((IPAddress)data).ToString();
}

이제 IP를 클라이언트에 다시 보낼 수 있습니다.

도움이 되었습니까?

해결책 5

나에게 딱 맞는 방법을 찾았어요.CommonTransportKeys.IPAddress에 액세스할 수 있는 사용자 지정 IServerChannelSinkProvider 및 IServerChannelSink를 구현하면 CallContext에 클라이언트 IP를 쉽게 추가할 수 있습니다.

public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, 
    IMessage requestmessage, ITransportHeaders requestHeaders, 
    System.IO.Stream requestStream, out IMessage responseMessage, 
    out ITransportHeaders responseHeaders, out System.IO.Stream responseStream)
{
    try
    {
        // Get the IP address and add it to the call context.
        IPAddress ipAddr = (IPAddress)requestHeaders[CommonTransportKeys.IPAddress];
        CallContext.SetData("ClientIP", ipAddr);
    }
    catch (Exception)
    {
    }

    sinkStack.Push(this, null);
    ServerProcessing srvProc = _NextSink.ProcessMessage(sinkStack, requestmessage, requestHeaders,
        requestStream, out responseMessage, out responseHeaders, out responseStream);

    return srvProc;
}

그런 다음 나중에(클라이언트로부터 요청을 받으면) 이렇게 CallContext에서 IP를 가져옵니다.

public string GetClientIP()
{
    // Get the client IP from the call context.
    object data = CallContext.GetData("ClientIP");

    // If the data is null or not a string, then return an empty string.
    if (data == null || !(data is IPAddress))
        return string.Empty;

    // Return the data as a string.
    return ((IPAddress)data).ToString();
}

이제 IP를 클라이언트에 다시 보낼 수 있습니다.

다른 팁

이는 더 깊이 살펴보고 원래 문제를 다시 생각해야 하는 질문 중 하나입니다.이 경우 "외부 IP 주소가 왜 필요한가요?"

문제는 컴퓨터에 외부 IP 주소가 없을 수 있다는 것입니다.예를 들어 내 노트북에는 라우터에서 할당한 내부 IP 주소(192.168.x.y)가 있습니다.라우터 자체에는 내부 IP 주소가 있지만 "외부" IP 주소도 내부입니다.이는 실제로 외부 인터넷 연결 IP 주소가 있는 DSL 모뎀과 통신하는 데에만 사용됩니다.

실제 질문은 "장치 2 홉을 어떻게 인터넷에 맞춰 IP 주소를 얻을 수 있습니까?" 그리고 대답은 일반적으로 그렇지 않습니다.적어도 이미 무시한 whatismyip.com과 같은 서비스를 사용하거나 응용 프로그램에 DSL 모뎀 비밀번호를 하드코딩하고 DSL 모뎀에 쿼리하고 관리 페이지를 화면 스크래핑하는 등 엄청난 해킹을 수행하지 않고는 할 수 없습니다. 모뎀을 교체한 경우).

편집하다:이제이를 리팩토링 된 질문에 적용하려면 "서버 .NET 구성 요소에서 클라이언트의 IP 주소를 어떻게 얻습니까?" Whatismyip.com과 마찬가지로 서버가 할 수있는 최선의 방법은 인터넷을 향한 장치의 IP 주소를 제공하는 것입니다. 이는 응용 프로그램을 실행하는 컴퓨터의 실제 IP 주소가 아닐 것입니다.노트북으로 돌아가서, 인터넷 연결 IP가 75.75.75.75이고 LAN IP가 192.168.0.112라면 서버는 75.75.75.75 IP 주소만 볼 수 있습니다.그것은 내 DSL 모뎀까지 도달할 것입니다.귀하의 서버가 내 노트북에 별도의 연결을 설정하려는 경우 먼저 DSL 모뎀과 그 사이의 모든 라우터와 내 노트북을 구성하여 서버에서 들어오는 연결을 인식하고 적절하게 라우팅해야 합니다.이를 수행하는 방법에는 여러 가지가 있지만 이 주제의 범위를 벗어납니다.

실제로 서버에서 클라이언트로 연결을 시도하는 경우 WTF 영역을 탐구하고 있기 때문에(또는 적어도 애플리케이션을 배포하기가 훨씬 더 어려워지기 때문에) 디자인을 다시 생각해 보십시오.

Dns.GetHostEntry(Dns.GetHostName());IP 주소 배열을 반환합니다.첫 번째 IP는 외부 IP여야 하고 나머지는 NAT 뒤의 IP입니다.

그래서:

IPHostEntry IPHost = Dns.GetHostEntry(Dns.GetHostName());
string externalIP = IPHost.AddressList[0].ToString();

편집하다:

일부 사람들에게는 이것이 효과가 없다는 보고가 있습니다.제 경우에는 가능하지만 네트워크 구성에 따라 작동하지 않을 수도 있습니다.

그냥 사용하는 것이 더 좋습니다 http://www.whatismyip.com/automation/n09230945.asp 자동 조회를 위해서만 IP를 출력합니다.

다른 사람에게 의존하지 않는 것을 원한다면 자신만의 페이지를 올려보세요 http://www.unkwndesign.com/ip.php 단지 빠른 스크립트입니다.

<?php
echo 'Your Public IP is: ' . $_SERVER['REMOTE_ADDR'];
?>

여기서 유일한 단점은 요청을 생성하는 데 사용된 인터페이스의 외부 IP만 검색한다는 것입니다.

Jonathan Holland의 대답은 기본적으로 정확하지만 Dns.GetHostByName 뒤의 API 호출은 상당히 시간이 많이 걸리며 코드를 한 번만 호출하면 되도록 결과를 캐시하는 것이 좋습니다.

주요 문제는 공용 IP 주소가 애플리케이션을 실행하는 로컬 컴퓨터와 반드시 연관되어 있지는 않다는 것입니다.방화벽을 통해 내부 네트워크에서 변환됩니다.로컬 네트워크를 조사하지 않고 실제로 공인 IP를 얻으려면 인터넷 페이지에 요청하고 결과를 반환하는 것입니다.공개적으로 사용 가능한 WhatIsMyIP.com 유형 사이트를 사용하고 싶지 않은 경우 쉽게 사이트를 만들고 직접 호스팅할 수 있습니다. 웹 서비스로 사용하는 것이 바람직하므로 애플리케이션 내에서 간단한 비누 호환 호출을 할 수 있습니다.비하인드 스토리 게시물만큼 화면 캡처를 많이 수행하고 응답을 읽을 필요는 없습니다.

어댑터에 바인딩된 IP만 원하는 경우 WMI 및 Win32_NetworkAdapterConfiguration 클래스를 사용할 수 있습니다.

http://msdn.microsoft.com/en-us/library/aa394217(VS.85).aspx

Patrik의 솔루션이 저에게 효과적입니다!

내가 만든 하나 중요한 변화.프로세스 메시지에서 다음을 설정했습니다. CallContext 이 코드를 사용하여:

// try to set the call context
LogicalCallContext lcc = (LogicalCallContext)requestMessage.Properties["__CallContext"];
if (lcc != null)
{
    lcc.SetData("ClientIP", ipAddr);
}

이렇게 하면 IP 주소가 올바른 CallContext에 배치되므로 나중에 다음을 사용하여 검색할 수 있습니다.GetClientIP().

글쎄, 당신이 가지고 있다고 가정 System.Net.Sockets.TcpClient 클라이언트에 연결하면 (서버에서) 다음을 사용할 수 있습니다. client.Client.RemoteEndPoint.이것은 당신에게 System.Net.EndPoint 클라이언트를 가리키며;저것 ~해야 한다 다음의 인스턴스를 포함합니다. System.Net.IPEndPoint 하위 클래스이지만 해당 조건에 대해서는 잘 모르겠습니다.캐스팅한 후 확인할 수 있습니다. Address 클라이언트의 주소를 가져오는 속성입니다.

간단히 말해서, 우리는

using (System.Net.Sockets.TcpClient client = whatever) {
    System.Net.EndPoint ep = client.Client.RemoteEndPoint;
    System.Net.IPEndPoint ip = (System.Net.IPEndPoint)ep;
    DoSomethingWith(ip.Address);
}

행운을 빌어요.

나는 이론적으로 라우터 뒤에 있는 동안에는 그런 일을 할 수 없다고 생각합니다(예:잘못된 IP 범위 사용) 외부 "도움말"을 사용하지 않고.

기본적으로 WebRequest를 수행하여 반환된 페이지를 구문 분석할 수 있습니다. http://whatismyipaddress.com

http://www.dreamincode.net/forums/showtopic24692.htm

이를 수행하는 가장 안정적인 방법은 다음과 같은 사이트를 확인하는 것입니다. http://checkip.dyndns.org/ 또는 이와 유사한 이유는 실제로 네트워크 외부로 이동할 때까지 외부 IP를 찾을 수 없기 때문입니다.그러나 이러한 URL을 하드코딩하면 최종 실패가 발생합니다.현재 IP가 다음과 같은 경우에만 이 확인을 수행할 수 있습니다. RFC1918 개인 주소(192.168.x.x 그 중 가장 친숙한 존재입니다.

실패하면 방화벽 외부에 자신만의 유사한 서비스를 구현할 수 있으므로 적어도 방화벽이 손상되었는지 알 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top