• Windows Phone学习笔记(8) — — UDP套接字


      上一篇写了如何进行TCP通信的套接字,这次来说一些怎么进行UDP的套接字通信,还用之前TCP套接字通信的那个示例页面,只是把后台的TCP通信改为UDP通信。首先我们先来修改SocketClient类

    View Code
        public class SocketClient
        {
            Socket _socket = null;
            static ManualResetEvent _clientDone = new ManualResetEvent(false);
            const int TIMEOUT_MILLISECONDS = 5000;
            const int MAX_BUFFER_SIZE = 2048;
    
            /// <summary>
            /// SocketClient构造函数
            /// </summary>
            public SocketClient()
            {
                //创建一个具有一些属性的套接字
                // AddressFamily.InterNetwork - 该套接字将使用IP版本4寻址方案来解决一个地址
                // SocketType.Dgram - 一个套接字,支持数据(消息)包
                // PrototcolType.Udp - 用户的数据协议(UDP)
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            }
    
            /// <summary>
            /// 使用已经建立的连接发送数据
            /// </summary>
            /// <param name="serverName">服务器名称</param>
            /// <param name="portNumber">数据发送到的端口号</param>
            /// <param name="data">发送到服务器的数据</param>
            /// <returns>发送请求的结果</returns>
            public string Send(string serverName, int portNumber, string data)
            {
                string response = "Operation Timeout";
    
                //我们用_socket对象初始化的连接方法
                if (_socket != null)
                {
                    // 创建一个SocketAsyncEventArgs对象
                    SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
    
                    //设置SocketAsyncEventArgs对象上下文的属性
                    socketEventArg.RemoteEndPoint = new DnsEndPoint(serverName, portNumber);
    
                    // 内联事件处理程序完成事件。
                    // Note: This event handler was implemented inline in order to make this method self-contained.
                    socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                    {
                        response = e.SocketError.ToString();
    
                        //开启UI线程
                        _clientDone.Set();
                    });
    
                    //添加数据到缓冲数据 Add the data to be sent into the buffer
                    byte[] payload = Encoding.UTF8.GetBytes(data);
                    socketEventArg.SetBuffer(payload, 0, payload.Length);
    
                    // Sets the state of the event to nonsignaled, causing threads to block
                    //设置事件的接收状态,阻塞UI线程
                    _clientDone.Reset();
    
                    // Make an asynchronous Send request over the socket
                    //让异步套接字发送请求
                    _socket.SendToAsync(socketEventArg);
    
                    //这对时间内如果没有反应的话,阻塞UI线程最大时间为TIMEOUT_MILLISECONDS设定的毫秒数
                    _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
                }
                else
                {
                    response = "Socket is not initialized";
                }
    
                return response;
            }
    
    
            /// <summary>
            /// Receive data from the server
            /// </summary>
            /// <param name="portNumber">The port on which to receive data</param>
            /// <returns>The data received from the server</returns>
            public string Receive(int portNumber)
            {
                string response = "Operation Timeout";
    
                //我们正在建立一个套接字接收
                if (_socket != null)
                {
                    // 创建一个SocketAsyncEventArgs对象
                    SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                    socketEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, portNumber);
    
                    // 设置缓冲区接收数据
                    socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
    
                    //内联事件处理程序完成事件。
                    // Note: This even handler was implemented inline in order to make this method self-contained.
                    socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                    {
                        if (e.SocketError == SocketError.Success)
                        {
                            //从缓冲区检索数据
                            response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
                            response = response.Trim('\0');
                        }
                        else
                        {
                            response = e.SocketError.ToString();
                        }
    
                        _clientDone.Set();
                    });
    
                    _clientDone.Reset();
                    _socket.ReceiveFromAsync(socketEventArg);
                    _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
                }
                else
                {
                    response = "Socket is not initialized";
                }
                return response;
            }
    
            /// <summary>
            /// 关闭套接字连接并且释放所有相关资源
            /// </summary>
            public void Close()
            {
                if (_socket != null)
                {
                    _socket.Close();
                }
            }
        }

    对比可以看到,在UDP通信中SocketClient中之后Send和Receive两个方法,这是因为UDP不需要先进行与服务器的连接。在改好SocketClient类之后,我们来修改下页面中的两个单机事件btnEcho_Click和btnGetQuote_Click,其它方法保留

    View Code
            private void btnEcho_Click(object sender, RoutedEventArgs e)
            {
                //清空日志
                ClearLog();
    
                // Make sure we can perform this action with valid data
                //确保我们可以执行这个动作与数据的有效
                if (ValidateRemoteHost() && ValidateInput())
                {
                    //实例化SocketClient
                    SocketClient client = new SocketClient();
    
                    // Attempt to send our message to be echoed to the echo server
                    //尝试发送消息响应服务器
                    Log(String.Format("Sending '{0}' to server ...", txtInput.Text), true);
                    string result = client.Send(txtRemoteHost.Text, ECHO_PORT, txtInput.Text);
                    Log(result, false);
    
                    //接收来自服务器的响应
                    Log("Requesting Receive ...", true);
                    result = client.Receive(ECHO_PORT);
                    Log(result, false);
    
                    //关闭套接字的连接
                    client.Close();
                }
            }
    
            private void btnGetQuote_Click(object sender, RoutedEventArgs e)
            {
                // Clear the log 
                ClearLog();
    
                // Make sure we can perform this action with valid data
                if (ValidateRemoteHost())
                {
                    SocketClient client = new SocketClient();
    
                    Log(String.Format("Requesting a quote from server '{0}' ...", txtRemoteHost.Text), true);
                    string dummyMessage = " ";
                    string result = client.Send(txtRemoteHost.Text, QOTD_PORT, dummyMessage);
                    Log(result, false);
    
                    // Receive response from the QOTD server
                    Log("Requesting Receive ...", true);
                    result = client.Receive(QOTD_PORT);
                    Log(result, false);
    
                    // Close the socket connection explicitly
                    client.Close();
                }
            }

    下面是触发btnEcho_Click和btnGetQuote_Click事件以后的截图

      

  • 相关阅读:
    DP--HDU 1003求数字串中的最大连续序列(含有DP过程详细分析)
    递归+DFS--简单迷宫问题--百练2802
    枚举--百练2812--恼人的青蛙(内含枚举基本思想总结)
    计蒜客:最大子阵
    hdu 4515 小Q系列故事——世界上最遥远的距离
    日期计算
    最大最小公倍数
    hdu 1568 Fibonacci
    矩阵快速幂
    矩阵乘法
  • 原文地址:https://www.cnblogs.com/renhao0118/p/2786185.html
Copyright © 2020-2023  润新知