#c# #udp
#c# #udp
Вопрос:
На моем компьютере запущены две сторонние программы, которые взаимодействуют друг с другом через UDP. Программа A — это просто приложение с пользовательским интерфейсом, которое подключается через UDP и позволяет пользователю отправлять определенные шестнадцатеричные команды программе B, которая отправляет обратно некоторое подтверждение в шестнадцатеричном формате. Я знаю, что программа B получает на порт 11001 и отправляет на порт 11000. Для начала я пытаюсь воссоздать программу A на C # в качестве консольного приложения. Я написал следующий код:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
network udpNetwork = new network();
Console.WriteLine("Hello World!");
udpNetwork.StartListener();
}
}
class network
{
private const int sendPort = 11001; //Port to transmit to
private const int receivePort = 11000; //Port to receive on
public void StartListener()
{
string IP_Address = Dns.GetHostByName(Environment.MachineName).AddressList[1].ToString();
IPAddress broadcast = IPAddress.Parse(IP_Address); //create IP address
IPEndPoint endpointSend = new IPEndPoint(broadcast, sendPort);
IPEndPoint endpointReceive = new IPEndPoint(broadcast, receivePort);
UdpClient udpServer = new UdpClient(AddressFamily.InterNetwork);
udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Client.Bind(endpointSend);
var packetData = new byte[] { 0x1F, 0x7F, 0x80, 0x1F, 0xFF };
try
{
udpServer.Connect(endpointSend);
udpServer.Send(packetData, packetData.Length);
udpServer.Close();
UdpClient udpReceive = new UdpClient(AddressFamily.InterNetwork);
udpReceive.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpReceive.Client.Bind(endpointReceive);
Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive);
string returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("This is the message you received "
returnData.ToString());
} catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
Код выполняется нормально до строки Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive);
, на которой он зависает. Я читал, что эта функция блокируется, что означает, что программа ожидает данных, но, очевидно, не получает их. Программа B, прослушивающая порт 11001, должна отправить ответ после того, как я отправил packetData, но этого не делает. Мне все равно не нужно использовать программу B, чтобы подтвердить, что она получает данные, которые я отправляю. Как я могу подтвердить, что программа B получает мои данные в первую очередь, или у меня есть какая-то другая проблема с моим кодом?
Редактировать:
Я отредактировал свой код, чтобы использовать IPV4, а не IPV6, в соответствии с предложением Jdweng. (Показано исправленным в приведенном выше фрагменте кода). Однако программа B по-прежнему не получает никаких данных, которые я могу подтвердить с помощью TCPView. После запуска программы из Visual Studio 2019 TCPView показывает, что программой B. не было получено пакетов.
Комментарии:
1. Вы используете метод блокировки (синхронный), который будет ждать, пока данные не будут получены. Таким образом, вы не получаете никаких данных. Вы должны использовать IPV4 (не IPV6): AddressFamily . InterNetworkV6. Также нулевой индекс равен IPV6, и вы должны использовать индекс один для IPV4: список адресов [1]
2. @jdweng Хорошо, отредактировали код, чтобы использовать IPV4. Я использовал TCPView, чтобы проверить, получает ли программа B какие-либо пакеты, но это все еще не так.
3. Что такое IP-адрес (многоадресная рассылка с 224 по 239)? Отправляете ли вы широковещательный или обычный UDP. Я бы использовал сниффер, такой как wireshark или fiddler, и посмотрел, правильно ли вы отправляете сообщения. Затем, после того, как вы получите отправку, попробуйте получить.
4. Если я запущу
ipconfig/all
, IPv4-адрес будет 192.168.11.113, а маска подсети — 255.255.255.0. Я отправляю широковещательный UDP — как только у меня будет что-то базовое, я хочу иметь возможность отправлять данные при нажатии кнопки.5. Таким образом, это не многоадресная рассылка. Тогда широковещательный адрес будет 192.169.11.255. Вы видите, что получаете сообщения с помощью сниффера. Широковещательный IP-адрес — это адрес 255 подсети. В противном случае он не транслируется.