비연결형 UDP 소켓


비연결형 UDP 소켓 (멀티캐스트)

 - 서버와 클라이언트를 나누어 작업 할 필요가 없다.

 - 프로그램이 켜진 모두가 동일한 코멘트를 받는다. 심지어 자기 자신도, 

 


///
/// superSc
/// 2014.10.7
///

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace UDPListerner.jsocket.udp
{
    public class SNUdpSocket
    {

        public enum UdpStatus
        {
            Initialize,
            READY_TO_READ,
            END_READ,
        }

        #region Events

        public event EventHandler<TraceEventArg> TraceEvent;
        public event EventHandler<StatusEventArg> StatusEvent;

        #endregion


        private UdpStatus _currentStatus = UdpStatus.Initialize;
        private IPAddress _multicastIp = MultiCastAddress.BASE;

        private UdpClient _udplistener;
        private Thread _listenThread;
        
        private IPEndPoint _localEp;
        private IPEndPoint _removeEp;
        
        private int _localPort = 18888;

        public SNUdpSocket(int localPort = 18888 , IPAddress multicastIp = null )
        {
            this._localPort = localPort;
            if(multicastIp != null) this._multicastIp = multicastIp;
            SetupUdpListener();
        }

        public void Dispose()
        {
            _listenThread.Abort();
        }




        #region Setup and Receive
        

        private void SetupUdpListener()
        {
            _udplistener = new UdpClient();
            _udplistener.Client.ExclusiveAddressUse = false;
            //option : http://msdn.microsoft.com/ko-kr/library/system.net.sockets.socketoptionname(v=vs.110).aspx
            _udplistener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            _localEp = new IPEndPoint(IPAddress.Any , _localPort);
            _removeEp = new IPEndPoint(_multicastIp, _localPort);
            _udplistener.Client.Bind(_localEp);
            _udplistener.JoinMulticastGroup(_multicastIp);

            _listenThread = new Thread(new ThreadStart(Receive));
            _listenThread.IsBackground = true;
            _listenThread.Start();
        }

        private void Receive()
        {
            while (true)
            {
                StatusEventDispatch(UdpStatus.READY_TO_READ);

                byte[] data = _udplistener.Receive(ref _localEp);

                StatusEventDispatch(UdpStatus.END_READ , data);
            }
        }

        #endregion





        #region DispatchEvent

        private void TraceEventDispatch(string message)
        {
            if (TraceEvent != null)
                TraceEvent(this, new TraceEventArg() { message = message });
        }

        private void StatusEventDispatch(UdpStatus status , byte[] data = null)
        {
            _currentStatus = status;
            if (StatusEvent != null)
                StatusEvent(this, new StatusEventArg() { status = status , data = data });
        }

        #endregion




        #region Sender
        
        public void SendBroadCast(string message)
        {
            byte[] data = System.Text.Encoding.Default.GetBytes(message);
            _udplistener.Send(data, data.Length, _removeEp);
        }

        #endregion
    }



    #region Multicast address
    
    public class MultiCastAddress
    {
        // 필요에 따라 추가 할것
        //http://en.wikipedia.org/wiki/Multicast_address




        /// <summary>
        /// Base address (reserved)
        /// </summary>

        public static readonly IPAddress BASE = IPAddress.Parse("224.0.0.0");


        /// <summary>
        /// The All Hosts multicast group addresses all hosts on the same network segment.
        /// </summary>
        public static readonly IPAddress ALL_HOST_GROUP = IPAddress.Parse("224.0.0.1");



    }

    #endregion




    #region EventArgs

    public class TraceEventArg : EventArgs
    {
        public string message;
    }

    public class StatusEventArg : EventArgs
    {
        public SNUdpSocket.UdpStatus status;
        public byte[] data;
    }




    #endregion
}



활용

using JUtil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using UDPListerner.jsocket.udp;

namespace UDPListerner
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
        }

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                AppStart();
            }));
        }



        private SNUdpSocket udpListener;
        private void AppStart()
        {
            TraceBox.InitailizeTraceBOX(this._traceBox);

            udpListener = new SNUdpSocket();
            udpListener.StatusEvent += udpListener_StatusEvent;
            TraceBox.trace("App Start");
        }

        

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            udpListener.Dispose();
        }

        void udpListener_StatusEvent(object sender, StatusEventArg e)
        {
            TraceBox.trace("status" , e.status);
            if (e.data != null)
            {
                var data = System.Text.Encoding.Default.GetString(e.data);
                TraceBox.trace("data receive > ", data);
            }
        }



        #region button handles

        private void Ck_OpenUDP(object sender, RoutedEventArgs e)
        {

        }

        private void Ck_SendMessage(object sender, RoutedEventArgs e)
        {
            udpListener.SendBroadCast(this._chattx.Text);
        }

        #endregion
    }
}


저작자 표시
신고
Yamecoder 야매코더_
분류없음 2017.01.31 14:09
Powerd by Tistory, designed by criuce
rss