我找了一下书,还真没有返回客户端ip的属性,
实在不行,久通过dns类来解析,把这个方法加入到远程对象中

解决方案 »

  1.   

    我是联通的SP,我想用C#写接收与发送的Socket Service的程序,人家一般都是用VC++的,但我不会用VC++。请问在性能上有没什么大碍?
      

  2.   

    first, create your own ServerChannelSink class and ServerChannelSinkProvider classusing System;
    using System.Runtime.Remoting.Channels;
    using System.Net;
    using System.Runtime.Remoting.Messaging;
    using System.Collections;
    using System.IO;public class CClientIPInjectorSink : BaseChannelObjectWithProperties,IServerChannelSink
    {
        private IServerChannelSink _nextSink;
        
        public CClientIPInjectorSink(IServerChannelSink nextSink)
        {
    _nextSink = nextSink;
        }
     
        public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack,
            object state, 
            IMessage msg, 
            ITransportHeaders headers,
            Stream stream) 
        {
            //get the client's ip address, and put it in the call context. 
            //This value will be extracted later so we can determine the actual
            //address of the client.
            try
            {
                IPAddress IPAddr = (IPAddress)headers[CommonTransportKeys.IPAddress];
       CallContext.SetData("ClientIP", IPAddr);
            }
            catch{}        //forward to stack for further processing
            sinkStack.AsyncProcessResponse(msg, headers,stream);
        }    public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack,
    object state,
    IMessage msg,
    ITransportHeaders headers)
        {
    return null;
        }    public IServerChannelSink NextChannelSink
        {
    get
    {
                 return _nextSink;
    }
        }    public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
    IMessage requestMsg,
    ITransportHeaders requestHeaders,
    Stream requestStream,
    out IMessage responseMsg,
    out ITransportHeaders responseHeaders,
    out Stream responseStream)
        {
            //get the client's ip address, and put it in the call context. 
            //This value will be extracted later so we can determine the actual
            //address of the client.
            try
            {
    IPAddress IPAddr = (IPAddress)requestHeader[CommonTransportKeys.IPAddress];
    CallContext.SetData("ClientIP", IPAddr);
            }
            catch{} //pushing onto stack and forwarding the call
    sinkStack.Push(this,null); ServerProcessing srvProc = 
               _nextSink.ProcessMessage(sinkStack,requestMsg,
    requestHeaders, requestStream, 
                                out responseMsg,out responseHeaders, 
                                out responseStream);
    if(srvProc == ServerProcessing.Complete)
    {
    //TODO - implement post processing
    }
    return srvProc;
        }
    }//this class is used as the sink provider that creates the 
    //CClientiPInjectorSink. It is used by the channel
    //so that we can get the caller's ip address
    public class CClientIPInjectorSinkProvider : IServerChannelSinkProvider
    {    private IServerChannelSinkProvider _nextProvider;    public CClientIPInjectorSinkProvider(){}    public CClientIPInjectorSinkProvider(IDictionary properties, 
                                            ICollection providerdata){}    public IServerChannelSink CreateSink(IChannelReceiver channel)
        {
    //create other sinks in the chain
    IServerChannelSink nextSink = _nextProvider.CreateSink(channel);
    return new CClientIPInjectorSink(nextSink);
        }
        public void GetChannelData(IChannelDataStore channelData)
        {
    //not needed
        }    public IServerChannelSinkProvider Next
        {
    get
    {
                  return _nextProvider;
    }
    set
    {
         _nextProvider = value;
    }
        }
    }
      

  3.   

    then use it to declare your channel//this part is done where you declare your channelHashtable props;
    props.Add("port", 10000);//create the binary server formatter sink
    BinaryServerFormatterSinkProvider BinProvider = new BinaryServerFormatterSinkProvider();
    BinProvider.TypeFilterLevel = 
    System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;//Create the ip injector sink
    CClientIPInjectorSinkProvider IpInjProvider = new CClientIPInjectorSinkProvider();//link the providers
    BinProvider.Next = IpInjProvider;System.Runtime.Remoting.Channels.Tcp.TcpChannel _PublicChannel 
    = new System.Runtime.Remoting.Channels.Tcp.TcpChannel(props, Nothing,BinProvider);
    _PublicChannel.StartListening(null);
      

  4.   

    sorry, forgot one thing. the way to get the IP back:IPAddress clientIP = (IPAddress)CallContext.GetData("ClientIP");
      

  5.   

    谢谢cqing,因为我的客户端已经发布了,用的是HTTP通道,如果重写接收器链,升级很麻烦呀,有没有在服务器端直接接受的??
      

  6.   

    这个就是Server端的呀,你要是用的是HTTP,那就把TcpChannel改成HttpChannel好了。
      

  7.   

    谢谢Cqing()!!
    TO:ermachao() ,客户端挺难获取动态的IP哦。