Windows Phone 7 下 Socket(TCP) 与 PC 通讯

Windows Phone 7 下 Socket(TCP) 与 PC 通讯,使用 WP7 模拟器与 PC 上的 Simple TCP 服务进行通讯。


TCP 客户端主要实现 Socket 连接的建立、数据的发送与接收和关闭已经建立的 Socket。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

// 手动增加的
using System.Net.Sockets;
using System.Threading;
using System.Text;

namespace SocketClientTest
{
    public class SocketClient
    {
        Socket socket = null;

        // 当一个异步操作完成时, 用于通知的事件对象
        static ManualResetEvent socketDone = new ManualResetEvent(false);

        // 异步操作超过时间定义. 如果在此时间内未接收到回应, 则放弃此操作.
        const int TIMEOUT_MILLISECONDS = 5000;

        // 最大接收缓冲
        const int MAX_BUFFER_SIZE = 2048;

        // Socket 连接到指定端口的服务器
        // hostName 服务器名称
        // portNumber 连接端口
        // 返回值: 连接结果返回的字符串
        public string Connect(string hostName, int portNumber)
        {
            string result = string.Empty;

            // 创建 DnsEndPoint. 服务器的端口传入此方法
            DnsEndPoint hostEntry = new DnsEndPoint(hostName, portNumber);

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // 创建一个 SocketAsyncEventArgs 对象用于连接请求
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.RemoteEndPoint = hostEntry;

            // Inline event handler for the Completed event.
            // 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)
                    {
                        result = e.SocketError.ToString();
                        // 标识请求已经完成, 不阻塞 UI 线程
                        socketDone.Set();
                    }
                );

            socketDone.Reset();
            socket.ConnectAsync(socketEventArg);
            socketDone.WaitOne(TIMEOUT_MILLISECONDS);

            return result;
        }

        public string Send(string data)
        {
            string response = "Operation Timeout";

            if (socket != null)
            {
                // 创建 SocketAsyncEventArgs 对象、并设置对象属性
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
                socketEventArg.UserToken = null;

                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                        {
                            response = e.SocketError.ToString();
                            socketDone.Set();
                        }
                    );

                // 将需要发送的数据送入发送缓冲区
                byte[] payload = Encoding.UTF8.GetBytes(data);
                socketEventArg.SetBuffer(payload, 0, payload.Length);

                socketDone.Reset();
                socket.SendAsync(socketEventArg);
                socketDone.WaitOne(TIMEOUT_MILLISECONDS);
            }
            else
            {
                response = "Socket is not initialized";
            }

            return response;
        }

        public string Receive()
        {
            string response = "Operation Timeout";

            if (socket != null)
            {
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
                socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);

                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();
                            }

                            socketDone.Set();
                        }
                    );

                socketDone.Reset();
                socket.ReceiveAsync(socketEventArg);
                socketDone.WaitOne(TIMEOUT_MILLISECONDS);
            }
            else
            {
                response = "Socket is not initialized";
            }

            return response;
        }

        /// <summary>
        /// Closes the Socket connection and releases all associated resources
        /// </summary>
        public void Close()
        {
            if (socket != null)
            {
                socket.Close();
            }
        }
    }
}


对 TCP 客户端的使用如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

/*
 * 可以运行在 Windows Phone 7 模拟器上与 PC 进行 Socket 通讯。从 Simple TCP 服务获取相应的回应。
*/

namespace SocketClientTest
{
    public partial class MainPage : PhoneApplicationPage
    {
        const int ECHO_PORT = 7;  // 回应端口: 配合 PC 系统的 Simple TCP 服务使用,回应接收到的字符串
        const int QOTD_PORT = 17; // 当日语录端口:  配合 PC 系统的 Simple TCP 服务使用

        // 构造函数
        public MainPage()
        {
            InitializeComponent();

            txtRemoteHost.Text = "yonghang-pc";       // 计算机名:可以从 桌面->计算名->属性中查看到
            txtInput.Text = "Test socket 测试";       // 发送的字符串
        }

        private void btnEcho_Click(object sender, RoutedEventArgs e)
        {
            // 清空 log 
            ClearLog();

            // 确认输入是否有效
            if (ValidateRemoteHostInput() && ValidateEditEchoInput())
            {
                // 初始化 SocketClient 实例
                SocketClient client = new SocketClient();

                // 开始连接 Echo Server
                Log(String.Format("Connecting to server '{0}' over port {1} (echo) ...", txtRemoteHost.Text, ECHO_PORT), true);
                string result = client.Connect(txtRemoteHost.Text, ECHO_PORT);
                Log(result, false);

                // 发送字符串到 Echo Server
                Log(String.Format("Sending '{0}' to server ...", txtInput.Text), true);
                result = client.Send(txtInput.Text);
                Log(result, false);

                // 接收来自 Echo Server 的回应
                Log("Requesting Receive ...", true);
                result = client.Receive();
                Log(result, false);

                // 关闭 Socket 连接
                client.Close();
            }

        }

        // 获取当日语录
        private void btnGetQuote_Click(object sender, RoutedEventArgs e)
        {
            ClearLog();

            if (ValidateRemoteHostInput())
            {
                SocketClient client = new SocketClient();

                Log(String.Format("Connecting to server '{0}' over port {1} (Quote of the Day) ...", txtRemoteHost.Text, QOTD_PORT), true);
                string result = client.Connect(txtRemoteHost.Text, QOTD_PORT);
                Log(result, false);

                Log("Requesting Receive ...", true);
                result = client.Receive();
                Log(result, false);

                client.Close();
            }
        }

        // 判断是否有输入
        private bool ValidateEditEchoInput()
        {
            if (String.IsNullOrWhiteSpace(txtInput.Text))
            {
                MessageBox.Show("Please enter string to send.");
                return false;
            }

            return true;
        }

        // 判断是否有输入
        private bool ValidateRemoteHostInput()
        {
            if (String.IsNullOrWhiteSpace(txtRemoteHost.Text))
            {
                MessageBox.Show("Please enter host name!");
                return false;
            }

            return true;
        }

       // 在 TextBox 中输出测试信息
        private void Log(string message, bool isOutgoing)
        {
            string direction = (isOutgoing) ? ">> " : "<< ";
            txtOutput.Text += Environment.NewLine + direction + message;
        }

        // 清空测试信息
        private void ClearLog()
        {
            txtOutput.Text = String.Empty;
        }
    }
}


你可能感兴趣的:(Windows Phone 7 下 Socket(TCP) 与 PC 通讯)