Ошибка сокета при удаленном взаимодействии .NET между двумя машинами

В проекте, над которым мы работаем, мы используем удаленное взаимодействие .NET для связи между сервером и клиентом. До сих пор мы тестировали его на той же машине, и он работал, используя localhost и произвольный номер порта. Однако при тестировании между двумя машинами в одной сети с использованием основной компонент работает, но прокси-объект не работает.

Мы используем файлы конфигурации, чтобы установить имя и порт сервера, например:

<setting name="ServerName" serializeAs="String">
    <value>192.168.1.141</value>
</setting>
<setting name="Port" serializeAs="String">
    <value>9932</value>
</setting>

Клиент настраивает объект удаленного взаимодействия следующим образом:

_port = global::ConsoleClient.Properties.Settings.Default.Port;
_servername = global::ConsoleClient.Properties.Settings.Default.ServerName;

string url = "tcp://" + _servername + ":" + _port + "/Lobby";

try
{
    ChannelServices.RegisterChannel(new TcpClientChannel(), false);
    Lobby lobby = (Lobby)Activator.GetObject(
        typeof(Lobby), url);
}
catch (Exception e)
{
}

Это нормально работает, и мы можем вызывать методы объекта лобби. Однако позже в коде мы возвращаем другой объект, таблицу, как показано ниже:

table_proxy = lobby_proxy.joinTable(userID, i);

где lobby_proxy - тот же объект лобби в предыдущем коде. Сервер настроен следующим образом:

_port = global::Server.Properties.Settings.Default.Port;
_lobby = new Lobby(_db);

try
{
    TcpServerChannel channel = new TcpServerChannel(_port);
    ChannelServices.RegisterChannel(channel, false);
    RemotingConfiguration.RegisterWellKnownServiceType(typeof(Lobby),
            "Lobby", WellKnownObjectMode.Singleton);
    RemotingServices.Marshal((_lobby), "Lobby");
    System.Console.WriteLine("Press Any Key");
}
catch (Exception e)
{
    System.Console.WriteLine(e);
}

Это отлично работает при запуске на одной машине, но вызывает следующую ошибку при запуске на разных машинах:

System.Net.Sockets.SocketException (0x80004005): A socket operation was attempte
d to an unreachable network 169.254.171.86:9932
   Exit
Server stack trace:
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddre
ss socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint
 ipEndPoint)
   at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket()
   at System.Runtime.Remoting.Channels.RemoteConnection.GetSocket()
   at System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machinePortA
ndSid, Boolean openNew)
   at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWit
hRetry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream)
   at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage
(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITranspor
tHeaders& responseHeaders, Stream& responseStream)
   at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMess
age(IMessage msg)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage req
Msg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgDa
ta, Int32 type)
   at JackOfTrades.Common.Table.GetTableData(Boolean full)

Глядя на верхнюю часть, я вижу IP-адрес, который я не узнаю, он не находится ни в сети, ни в IP-адресе маршрутизатора.

Есть мысли о том, что не так? Помощь будет принята с благодарностью!


person achinda99    schedule 09.11.2010    source источник
comment
IP: 169.254.171.86 выглядит как автоматически настроенный IP-адрес Windows, который обычно является результатом сетевого адаптера (например, вторичного адаптера), который не подключен к сети. Есть ли где-нибудь в коде, где вы пытаетесь определить IP-адрес локального компьютера и, возможно, не указываете, для какого адаптера вы получаете адрес?   -  person CodingGorilla    schedule 09.11.2010


Ответы (2)


Вам необходимо настроить TcpServerChannel со следующим параметром:

bindTo
Строка, указывающая IP-адрес сетевой карты (NIC), к которой должен быть привязан канал сервера. Значение по умолчанию - System.Net.IPAddress.Any.

http://msdn.microsoft.com/en-us/library/bb397831.aspx

ОБНОВЛЕНО:

IDictionary properties = new Hashtable();
properties["port"] = 9932;
properties["bindTo"] = "192.168.1.141";
TcpServerChannel channel = new TcpServerChannel(properties, null);
ChannelServices.RegisterChannel(channel,  false);
person QrystaL    schedule 09.11.2010
comment
Я изучал это и не могу понять, как использовать bindTo в TcpServerChannel. Любые ресурсы, которые показывают, как? Кажется, это недоступный вариант. - person achinda99; 09.11.2010

Адрес 168.254.x.x обычно отображается, когда сетевой адаптер не может получить адрес DHCP.

Я бы хотел убедиться, что машина, на которой вы запускаете этот код, имеет действительный IP-адрес.

person Moose    schedule 09.11.2010
comment
Что ж, я тестирую это в домашней сети, где маршрутизатор предоставляет IP-адреса 192.168.1.x. И правильные IP-адреса используются в файлах конфигурации для создания соединения. Я не уверен, откуда тянется 168.254.x.x. - person achinda99; 09.11.2010