2014-09-15 1 views
1

Я делаю проект, я хочу получать ловушки SNMP с устройства (просто, если вы хотите узнать). Я использовал код из этого примера http://www.snmpsharpnet.com/?page_id=117, и я пытаюсь просто настроить функцию barebones из этого. Но то, что я не понимаю здесь:Почему мне нужно определить конечную точку в гнезде дважды, чтобы начать прием данных?

public bool InitializeReceiver() 
{ 
     _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
     EndPoint localEP = new IPEndPoint(IPAddress.Parse(ip), port); 
     _socket.Bind(localEP); 

    if (!RegisterReceiveOperation()) 
     return false; 

    return true; 
} 

В этой строке я установить IP-адрес устройства и порта я хочу слушать тоже не так ли?

EndPoint localEP = new IPEndPoint(IPAddress.Parse(ip), port); 

А потом здесь

public bool RegisterReceiveOperation() 
{ 
    _peerIP = new IPEndPoint(IPAddress.Any, 0); 
    EndPoint ep = (EndPoint)_peerIP; 
    _inbuffer = new byte[64 * 1024]; 
    _socket.BeginReceiveFrom(_inbuffer, 0, 64 * 1024, 
     SocketFlags.None, ref ep, new AsyncCallback(ReceiveCallback), _socket); 
    return true; 
} 

Что такое _peerIP? Я установил его в тот же IP-адрес и порт, что и раньше? Или я оставлю это так?

Также, как примечание, исходный код с сайта работает, и я получаю ловушки правильно, но в своем приложении я хочу, чтобы соединение было более управляемым, и я не могу его постоянно проверять. Поэтому, если кто-то сможет прояснить, что такое разные IPEndPoint, это будет здорово.

Примечание 2: Я удалил много попыток и поймал блоки из моего измененного кода, который я опубликовал здесь, и другие материалы, которые, как я думаю, не имеют никакого отношения к этому вопросу.

ответ

2

Соединительная связь всегда включает в себя две конечные точки: локальную конечную точку (ту, которую вы слушаете), и удаленную конечную точку (тот, с которым вы получаете или подключаетесь). С ориентированными на бесконтактные протоколы, такими как UDP, нет необходимости связываться с локальной конечной точкой. Однако, если вы явно не привязаны к определенной локальной конечной точке, поставщик автоматически выберет любую доступную. Ну, на самом деле то же самое верно и для протоколов, ориентированных на соединение, а также при использовании локальной конечной точки для подключения к удаленному хосту вместо прослушивания входящих соединений.

Конечной точкой в ​​семействе методов ReceiveFrom является конечная точка, из которой вы ожидаете данные.Если вы готовы принять данные с любой конечной точки, вам следует указать IPAddress.Any и номер порта, равный нулю. Если вы предоставляете более конкретную конечную точку, то любые данные из других источников молча отбрасываются и получаются только данные с указанной конечной точки. Обратите внимание, что параметр передается по ссылке. По возврату метода переменная будет содержать фактическую конечную точку, из которой были получены данные.

Итак, подведение итогов: вам нужно определить конечную точку дважды, потому что вы указываете как локальные, так и удаленные конечные точки. Кроме того, вы можете указать IP-адрес и номер порта удаленного устройства в методе BeginReceiveFrom, если заранее знаете эту информацию и ожидаете, что она никогда не изменится (что маловероятно).

+1

Спасибо, очень помогло мне понять – Vajura

+1

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

3

Взятые из secion Socket.Bind(..) MSDN page

@Remarks:

Перед вызовом Bind, вы должны сначала создать местного IPEndPoint из которого вы намерены для передачи данных.

Теперь эта часть взята из Socket.BeginReceiveFrom(..) MSDN page

@Parameter в 'remoteEP':

конечную точку, которая представляет источник данных.

И с Примечания:

Перед вызовом BeginReceiveFrom, вы должны явно связать сокет с локальной конечной точки, используя метод Bind, или BeginReceiveFrom бросит SocketException.

+0

M8 Я читал это сам, но я не понимаю, что вторая конечная точка находится внутри BeginReceiveFrom, так как я уже установил мой сокет в ip и порт, который я тоже хочу слушать. Получает ли он себя после получения данных, поэтому я могу оставить его пустым? – Vajura

+0

Один из методов «Связывание» - это порт, к которому вы хотите установить связь, и тот, который находится внутри метода BeginReceiveFrom, является IP-адресом, откуда поступают данные. Это немного запутывает внутри вашего кода, поскольку ваше соединение находится в локальной сети. Если вы прочтете части, которые я сделал смелыми, я уверен, что вы их получите. –

+0

Но меня смущает то, что я устанавливаю IP-адрес в BIND, где я тоже хочу общаться. Так что если это не было в локальной сети (к которой это не будет позже) в bind я установил IPAddress и PORT, и мне не нужно устанавливать что-либо в BeginReceiveFrom EndPoint (или существенный IPAddress.Any и 0 в качестве порта)? – Vajura