ProgramingTip

Windows Phone 8의 UDP 멀티 캐스트 그룹

bestdevel 2021. 1. 8. 23:04
반응형

Windows Phone 8의 UDP 멀티 캐스트 그룹


OK 이것은 내가 지금 며칠 동안 알아 내려고 노력해온 것입니다. Windows Phone 7에는 전화가 멀티 캐스트 그룹에 가입 한 다음 그룹에 메시지를 보내고 서로 대화하는 응용 프로그램이 있습니다. 참고-전화 간 통신입니다.

이제 Visual Studio 2012의 '전화 8로 변환'기능을 사용하여 지금 까지이 응용 프로그램을 Windows Phone 8로 이식합니다. 전화 대 전화 통신을 테스트 할 때까지. 핸드셋은 그룹에 잘 있고, 보이며 데이터 그램을 OK로 보냅니다. 그룹에 전송 된 메시지도 수신하지만 다른 휴대 전화에서 수신되는 휴대 전화는 없습니다.

내 페이지에있는 샘플 코드는 다음과 가변적입니다.

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

// A client receiver for multicast traffic from any source
UdpAnySourceMulticastClient _client = null;

// Buffer for incoming data
private byte[] _receiveBuffer;

// Maximum size of a message in this communication
private const int MAX_MESSAGE_SIZE = 512;

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    _client = new UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS), GROUP_PORT);
    _receiveBuffer = new byte[MAX_MESSAGE_SIZE];

    _client.BeginJoinGroup(
        result =>
        {
            _client.EndJoinGroup(result);
            _client.MulticastLoopback = true;
            Receive();
        }, null);
}

private void SendRequest(string s)
{
    if (string.IsNullOrWhiteSpace(s)) return;

    byte[] requestData = Encoding.UTF8.GetBytes(s);

    _client.BeginSendToGroup(requestData, 0, requestData.Length,
        result =>
        {
            _client.EndSendToGroup(result);
            Receive();
        }, null);
}

private void Receive()
{
    Array.Clear(_receiveBuffer, 0, _receiveBuffer.Length);
    _client.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length,
        result =>
        {
            IPEndPoint source;

            _client.EndReceiveFromGroup(result, out source);

            string dataReceived = Encoding.UTF8.GetString(_receiveBuffer, 0, _receiveBuffer.Length);

            string message = String.Format("[{0}]: {1}", source.Address.ToString(), dataReceived);
            Log(message, false);

            Receive();
        }, null);
}

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
    {
        return;
    }

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });

}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendRequest(txtInput.Text);
    }
}

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    SendRequest("start now");
}

UDP 스택을 간단히 테스트하기 위해 여기에있는 MSDN에서 샘플을 다운로드하고 한 쌍의 Windows Phone 7 장치에서 테스트가 예상대로 작동합니다. 그런 다음 Windows Phone 8로 변환하여 핸드셋에 배포했습니다. 다시 장치가 연결을 시작하는 것처럼 보이며 사용자가 이름을 입력 할 수 있습니다. 그러나 다시 장치는 다른 장치를 보거나 통신 할 수 없습니다.

마지막으로 새로운 DatagramSocket 구현을 사용하여 간단한 통신 테스트를 구현하고 다시 통신으로 시작되는 장치 간은 없습니다.

이것은 소켓 구현을 사용하는 페이지 뒤의 동일한 코드입니다.

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

private DatagramSocket socket = null;

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
        return;

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });
}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendSocketRequest(txtInput.Text);
    }
}

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    socket = new DatagramSocket();
    socket.MessageReceived += socket_MessageReceived;

    try
    {
        // Connect to the server (in our case the listener we created in previous step).
        await socket.BindServiceNameAsync(GROUP_PORT.ToString());
        socket.JoinMulticastGroup(new Windows.Networking.HostName(GROUP_ADDRESS));
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
}

private async void SendSocketRequest(string message)
{
    // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached.
    //DataWriter writer;
    var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(GROUP_ADDRESS), GROUP_PORT.ToString());
    //writer = new DataWriter(socket.OutputStream);
    DataWriter writer = new DataWriter(stream);

    // Write first the length of the string as UINT32 value followed up by the string. Writing data to the writer will just store data in memory.
   // stream.WriteAsync(
    writer.WriteString(message);

    // Write the locally buffered data to the network.
    try
    {
        await writer.StoreAsync();
        Log(message, true);
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
    finally
    {
        writer.Dispose();
    }
}

void socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    try
    {
        uint stringLength = args.GetDataReader().UnconsumedBufferLength;
        string msg = args.GetDataReader().ReadString(stringLength);

        Log(msg, false);
    }
    catch (Exception exception)
    {
        throw;
    }
}

어젯밤 나는 집 무선 네트워크에서 핸드셋을 테스트하기 위해 집으로 가져 갔고, 장치 통신이 성공했습니다.

요약하자면 내 레거시 Windows Phone 7 코드는 회사 네트워크에서 잘 실행됩니다. Windows Phone 8에 대한 포트 (실제 코드 변경 없음)는 장치 간 통신을 전송하지 않습니다. 이 코드는 내 홈 네트워크에서 작동합니다. 코드는 디버거가 연결된 상태에서 실행되며 실행 중에 오류나 예외의 징후가 없습니다.

내가 사용하는 핸드셋은 다음과 같습니다.

Windows Phone 7-Nokia Lumia 900 (* 2), Nokia Lumia 800 (* 3) Windows Phone 8-Nokia Lumia 920 (* 1), Nokia Limia 820 (* 2)

이들은 모두 최신 OS를 실행하고 있으며 개발자 모드입니다. 개발 환경은 Visual Studio 2012 Professional을 실행하는 Windows 8 Enterprise입니다.

업무용 무선 네트워크에 대해 많이 말할 수 없습니다. Phone 7 장치 외에는 문제가 없습니다.

내가 사용한 홈 무선 네트워크의 경우 '기본 설정'이 변경되지 않은 기본 BT 광대역 라우터입니다.

두 네트워크가 구성되는 방식에는 분명히 문제가 있지만 Windows Phone 8에서 UDP 메시지를 구현하는 방식에도 매우 분명한 문제가 있습니다.

이것이 저를 지금 화나게하고 있기 때문에 어떤 입력이라도 감사 할 것입니다.


루프백을 사용하는 것으로 나타났습니다. 나는 당신이 당신의 클라이언트로부터 메시지를 보낼 때 당신이 보낸 메시지도 받게 될 것이라는 것을 의미한다고 생각합니다. 이것은 수신 핸들러가 실행된다는 것을 의미합니다. 스레드 안전하지 않은 것처럼 보이는 방식으로 수신 버퍼를 지우는 효과가 있습니다. 수신 메소드에 try catch를 넣어보고 문제가 발생하는지 확인하십시오. 그러나 어떤 경우에도 공유 수신 버퍼를 사용하지 않을 수도 있습니다.


다른 멀티 캐스트 그룹에 가입 해 본 적이 있습니까? 224.0.1.1이 IANA 할당으로 사용중인 것으로 보이기 때문입니다. 여기에서 모두 찾을 수 있습니다 .

Windows Phone 8에서 일부 서비스는 들어오는 메시지 (예 : 커널 모드에서 실행되는 네트워크 서비스)를 수신하는 데 더 긴밀하게 연결되어 있으며 사용자에게 전달되지 않습니다.


UDP 멀티 캐스트는 내 경험상 Windows Phone 7에서 매우 이상하게 작동하므로 Windows Phone 8에서도 동일하게 확인해야합니다.

내 경험은 다음과 같습니다.

  1. 예를 들어 Windows Phone OS 7.1 (전환하기 전에 시도한 마지막 OS)에서 공식적으로 지원되는 항목을 확인하십시오. TCP 유니 캐스트, UDP 유니 캐스트 및 UDP 멀티 캐스트 클라이언트가 지원됩니다.
  2. 일부 버전의 Windows Phone은 클라이언트가 처음 열었을 때만 UDP 세션을 수신하도록 허용하고 세션이 10 초 이내에 수신됩니다. 이는 Windows Phone에서 일종의 보안 문제처럼 보입니다.
  3. 다른 주소로 시도 : 224.0.0.0에서 224.0.0.255까지 범위의 멀티 캐스트 주소는 "잘 알려진"예약 된 멀티 캐스트 주소입니다.
  4. 가상 머신과 실제 전화 장치에서 모두 확인하면 동작이 다를 수 있습니다.

참조 URL : https://stackoverflow.com/questions/13528262/udp-multicast-group-on-windows-phone-8

반응형