Странное поведение с сокетами на localhost - PullRequest
2 голосов
/ 19 октября 2010

У меня есть два приложения .net, взаимодействующих с сокетами через порт 5672, и все работает нормально.На стороне сервера я открываю соединение с помощью следующих простых строк кода:

IPAddress localAddr = Dns.GetHostEntry("localhost").AddressList[0];  
TcpListener socket = new TcpListener(localAddr, 5672);  
socket.Start();  

Если я пытаюсь запустить другое серверное приложение, происходит сбой, сообщая, что порт уже используется.
У меня естьтакже та же пара приложений, написанных на C ++ (не мной).
К моему удивлению, я могу одновременно запустить и сервер C ++, и .net.

Хуже всего то, что мой клиент C ++ можетНе связывается с моим сервером .net (ошибка «соединение отклонено»).

Чтобы понять мою проблему, я перечислил используемые порты с помощью команды:

netstat -a  

И в результате у меня было:
TCP 0.0.0.0:5672 <--- (это сервер c ++) <br>TCP [:: 1]: 5672 <--- (это сервер .net) </p>

В соответствии с моим кодом на C # адрес локального хоста не должен быть 0.0.0.0или 127.0.0.1?
Что происходит на моем сервере .net?
Что означает [:: 1]?

Примечание:
Если я изменю свой код на:

IPAddress localAddr = new IPAddress(new byte[]{0,0,0,0});  

, все работает нормально, и мой клиент C ++ связывается с сервером .net.

Ответы [ 4 ]

2 голосов
/ 02 августа 2012

Я использовал что-то вроде этого:

        IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname);

        IPAddress ipAddress = ipHostInfo.AddressList[0];

        foreach (IPAddress ip in ipHostInfo.AddressList)
        {
            AddressFamily af = ip.AddressFamily;
            if (af == AddressFamily.InterNetwork)
            {
                ipAddress = ip;
                break;
            }
        }
2 голосов
/ 19 октября 2010

Когда я запускаю следующий код:

        IPAddress localAddr = Dns.GetHostEntry("localhost").AddressList[0];
        IPAddress localAddr2 = Dns.GetHostEntry("localhost").AddressList[1];

Я получаю IPV6-адрес, который вы показали в localAddr, и "127.0.0.1" в localAddr2 (и в AddressList больше нет записей). Если вы хотите использовать IPv4, вы должны найти и использовать правильный адрес, проверив свойство AddressFamily в каждом IPAddress в вашем списке кандидатов AddressList.

По умолчанию вы не можете прослушивать одну и ту же пару порт / адрес из двух приложений. Если вы хотите сделать это (не уверен, почему вы это сделаете, так как из-за этого серверное приложение делает входящие подключения недетерминированными), вы можете сделать это, установив ExclusiveAddrUse в false на вашем TcpListener - заметьте, однако, что вы должны сделать это, пока слушатель Stop -подобен.

Поскольку ваше приложение на C ++ напрямую использует 0.0.0.0, оно ведет себя по-разному. Он использует адрес IPV4, поэтому конфликт с вашим IPV6 C # TcpListener.

не приводит к конфликту.
1 голос
/ 19 октября 2010

Dns.GetHostEntry("localhost").AddressList[0]; привязывается к обратному адресу петли IPv6, поэтому, когда вы вручную устанавливаете его на обратную петлю IPv4, он работает нормально.

попробуйте это

IPHostEntry host;
host = Dns.GetHostEntry("localhost");
Console.WriteLine("GetHostEntry(\"LocalHost\") returns:");
foreach (IPAddress ip in host.AddressList)
{
    Console.WriteLine("    {0}", ip);
}
Console.ReadLine();

Для Windows 7 я получаю следующий результат

GetHostEntry("LocalHost") returns:
    ::1
    127.0.0.1
0 голосов
/ 19 октября 2010

0.0.0.0 равно IPAddress.Any, оно привязывается ко всему доступному.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...