• 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)


    Silverlight 与服务器利用Socket通讯,实时从服务器获取数据(本文中的数据是地理坐标),由于没有GPS,所以本文在服务器写了一个构造新坐标的函数(本文是一个三角函数),然后利用Timer组件,实时调用,得到新的坐标,并将新的坐标发送给客户端,客户端接收到发回的新的坐标,并在地图相应的位置进行标识。最后在地图上我们就会看到一个自动绘制的三角函数曲线。

    关于本文的一点说明:

    1.由于时间和篇幅的关系,也由于本人能力有限,所以程序还存在很多bug,不够完善,也许你运行的时候还会抛异常,本文关注的是关键功能的实现,所以希望高手勿喷,如果您有更好的方法和建议欢迎留言分享。

    2.作者没有GPS设置,相信大多数也是一样,所以无法实际的模拟从GPS获取数据,在地图上展示,因此本文模拟在服务器动态实时的生成坐标数据,并实时发送给客户端。不过如果您有GPS设备,实际上实现的过程是一样。

    3.本文的坐标数据是自己写的一个三角函数,所以最后在地图上实时绘制的运动轨迹也是一个三角函数,当然也可以换成其他任意的轨迹,只要可以写出其坐标生成函数即可。

    4.本文的具体过程是客户端向服务器发送一个起始的坐标,当然也可以是其他的信息,只不过便于绘制和理解,所以用了一个坐标,服务器接收该坐标,并基于该坐标生成新的坐标数据。不过在实际的GPS中,只需要客户端发送位置请求,服务器将真实的GPS坐标数据发送给客户端即可。

    5.本文的服务器端部分代码来自于该博主的博文:

    http://www.cnblogs.com/webabcd/archive/2008/12/22/1359551.html

    在此感谢webabcd(王磊 MVP)的分享。

    下面就来看看具体实现的过程。

    一.服务器端

    在上一篇中说到了与服务器通信,大致上的过程是客户端发送一个信息,服务器接收客户端信息,服务器回复一条信息,客户端接收服务器信息。但在本文中,稍微有些不一样。

    在本文中,客户端发送位置请求(本文客户端发送一个用于构造新坐标的起始坐标点),然后服务器基于接收的起始坐标,实时的生成新的坐标数据,并不断的往客户端发送,客户端不断接受服务器发送来的新数据,并在地图上标示。所以这里不像之前客户端请求一次,服务器则回复一条信息。

     下面给出具体的代码I(可以参看上面给出链接的博文):

     服务器端界面如下:

    具体过程:

      1.1 启动策略文件服务

    复制代码
     #region Start The Policy Server 验证策略文件
                PolicySocketServer StartPolicyServer = new PolicySocketServer();
                Thread th = new Thread(new ThreadStart(StartPolicyServer.StartSocketServer));
                th.IsBackground = true;
                th.Start();
                #endregion
    复制代码
    PolicySocketServer 类在上一篇文章中给出:
    http://www.cnblogs.com/potential/archive/2013/01/23/2873035.html
    1.2 启动服务器端Socket服务,监听端口,连接Socket。
    1.2.1 声明类级别的变量
    复制代码
     //客户端传入的起始坐标
            private double startx = 0;
            private double starty = 0;
            //服务器端生成的新坐标
            private double X;
            private double Y;
            //判断是否成功接收服务器发来的新的坐标
            bool receivedCoor = false;
            //够找新坐标时的步长
            private double step = 0;
    复制代码
    1.2.2启动Socket服务,开始连接
    复制代码
        private void StartupSocketServer()
            {
                //定时器,每0.3秒运行一次指定的方法
                //这里可自己手动修改刷新数据的时间
                _timer = new System.Timers.Timer();
                _timer.Interval = 300;
                _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
                _timer.Start();
    
                //初始化Socket
                _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //创建终结点,获取当前主机IP
                IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
                IPEndPoint localEndPoint = new IPEndPoint(ipHost.AddressList[3], 4530);
                //Win7 启动了IPV6地址,所以是3,如果为XP系统可换成0,1再试试
                _syncContext.Post(ChangeIPText, ipHost.AddressList[3].ToString());
                //绑定端口
                _listener.Bind(localEndPoint);
                _listener.Listen(100);
    
                while (true)
                {
                    //重置ManualResetEvent,由线程来控制ManualResetEvent
                    _connectDone.Reset();
    
                    _listener.BeginAccept(new AsyncCallback(OnClientConnect), null);
    
                    _connectDone.WaitOne();
                }
            }
    复制代码
    复制代码
    private void OnClientConnect(IAsyncResult result)
            {
                _connectDone.Set();
                ClientSocketPacket client = new ClientSocketPacket();
                client.Socket = _listener.EndAccept(result);
                _clientList.Add(client);
                _syncContext.Post(ResultCallback, "客户端已经连接");
    
                try
                {
                    client.Socket.BeginReceive(client.Buffer, 0, client.Buffer.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), client);
                }
                catch (SocketException ex)
                {
                    HandleException(client, ex);
                }
            }
    复制代码

    1.3 接收数据

    复制代码
      private void OnDataReceived(IAsyncResult result)
            {
                ClientSocketPacket client = result.AsyncState as ClientSocketPacket;
                int count = 0;
                try
                {
                    if (client.Socket.Connected)
                        count = client.Socket.EndReceive(result);
                }
                catch (SocketException ex)
                {
                    HandleException(client,ex);
                }
    
                foreach (byte b in client.Buffer.Take(count))
                {
                    if (b == 0)
                        continue;
                    client.RececivedByte.Add(b);
                }
    
                string receivedString = UTF8Encoding.UTF8.GetString(client.Buffer, 0, count);
                if (client.Socket.Connected && client.Socket.Available == 0 && receivedString.Contains(_endMarker))
                {
                    string content = UTF8Encoding.UTF8.GetString(client.RececivedByte.ToArray());
                    content = content.Replace(_endMarker, "");
                    client.RececivedByte.Clear();
                    SendData("服务器端已经成功接收数据!");
                    _syncContext.Post(ResultCallback, "服务器在" + DateTime.Now.ToShortTimeString() + "接收数据:" + content);
                }
                //对接受的数据进行分析
                //便于简单,客户端发送的坐标字符串格式是"x|y"
                //所以这里只是简单的判断是否有‘|’标识符
                if (receivedString.Contains("|"))
                {
                    string[] coordinates = receivedString.Split('|');
                    startx = Convert.ToDouble(coordinates[0]);
                    starty = Convert.ToDouble(coordinates[1]);
                    _syncContext.Post(ChangeReceivedText, receivedString);
                    step = 0;
                    receivedCoor = true;
                }
    
                try
                {
                    // 继续开始接收客户端传入的数据
                    if (client.Socket.Connected)
                        client.Socket.BeginReceive(client.Buffer, 0, client.Buffer.Length, 0, new AsyncCallback(OnDataReceived), client);
                }
                catch (SocketException ex)
                {
                    HandleException(client, ex);
                }
            }
    复制代码

    1.5 发送数据等

    复制代码
     private void SendData(string data)
            {
                byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);
                for (int i = 0; i < _clientList.Count;i++ )
                {
    
                        if (_clientList[i].Socket.Connected)
                        {
                            _clientList[i].Socket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnDataSend), _clientList[i]);
                            _syncContext.Post(ResultCallback, "服务器在" + DateTime.Now.ToShortTimeString() + "发送数据:" + data);
                        }
                        else
                        {
                            _clientList[i].Socket.Close();
                            _clientList.Remove(_clientList[i]);
                        }
                    }
            }
    复制代码

    1.6 生成新坐标的方法,本文利用的只是一个简单的Sin三角函数,读者可构造自己的函数。

    复制代码
      private void newCoordinate(out double latitude, out double longitude, ref double step)
            {
                latitude = startx + 30 * step;
    
                longitude = starty + 100 * Math.Sin(step);
    
                step = step + 0.1;
            }
    复制代码

    1.7 Timer定时器的触发函数,定时向调用构造新坐标的方法,构造新的坐标,并发送数据的到客户端

    复制代码
      private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                //如果服务器成功接收客户端传入的坐标,则向服务器发送数据
                if (receivedCoor == true)
                {
                    newCoordinate(out X, out Y, ref step);
                    string lat = startx.ToString("#0.00");
                    string lon = starty.ToString("#0.00");
                    //将新的坐标发送给客户端
                    SendData(string.Format("{0}|{1}", X, Y));
                }
            }
    复制代码

    1.8 其他相关函数,用于更改UI

    复制代码
         private void ResultCallback(object result)
            {
                // 输出相关信息
                listBox1.Items.Add(result);
            }
    
            private void ChangeIPText(object str)
            {
                HostIPTextBox.Text = str.ToString();
            }
            private void ChangeReceivedText(object str)
            {
                ReceivedTextBox.Text = str.ToString();
            }
    复制代码

    1.9 开启Socket服务Button事件,及清除消息列表

    复制代码
     private void StartButton_Click(object sender, EventArgs e)
            {
                // 启动后台线程去运行 Socket 服务
                Thread thread = new Thread(new ThreadStart(StartupSocketServer));
                thread.IsBackground = true;
                thread.Start();
            }
    
            private void ClearButton_Click(object sender, EventArgs e)
            {
                listBox1.Items.Clear();
            }
    复制代码

    Main.cs

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

    二、Silverlight客户端

    UI界面如下:



    客户端实现的过程和上一篇文章差不多,代码几乎没有变化,只不过是连续的想服务器获取数据,代码如下:
    复制代码
      private void socketEventArg_Completed(object sender, SocketAsyncEventArgs e)
            {
               //检查是否发送出错
                if (e.SocketError != SocketError.Success)
                {
                    if (e.SocketError == SocketError.ConnectionAborted)
                    {
                        Dispatcher.BeginInvoke(() => MessageBox.Show("连接超时....请重试!"));
                    }
                    else if (e.SocketError == SocketError.ConnectionRefused)
                    {
                        Dispatcher.BeginInvoke(() => MessageBox.Show("无法连接到服务器端:"+e.SocketError));
                    }else
                    {
                        Dispatcher.BeginInvoke(() => MessageBox.Show("Socket连接已断开!"));
                    }
                    return;
                }
               //如果连接上,则发送数据
                if (e.LastOperation == SocketAsyncOperation.Connect)
                {
                        byte[] userbytes = (byte[])e.UserToken;
                        e.SetBuffer(userbytes, 0, userbytes.Length);
                        socket.SendAsync(e);
                        
                }//如果已发送数据,则开始接收服务器回复的消息
                else if (e.LastOperation == SocketAsyncOperation.Send)
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        listBox1.Items.Add("客户端在" + DateTime.Now.ToShortTimeString() + ",发送消息:" + MessageTextBox.Text);
                    });
                    byte[] userbytes = new byte[1024];
                    e.SetBuffer(userbytes, 0, userbytes.Length);
                    socket.ReceiveAsync(e);
                }//接收服务器数据
                else if (e.LastOperation == SocketAsyncOperation.Receive)
                {
                    string RecevieStr = Encoding.UTF8.GetString(e.Buffer, 0, e.Buffer.Length).Replace("\0", "");
                    Dispatcher.BeginInvoke(() =>
                    {
                        listBox1.Items.Add("服务器在" + DateTime.Now.ToShortTimeString() + ",回复消息:" + RecevieStr);
                    });
                   //分析服务器发送回来的坐标数据,数据格式“x|y”
                    if (RecevieStr.Contains("|"))
                    {
                        string[] coor = RecevieStr.Split('|');
                        //构造新的坐标点
                        MapPoint mp1 = new MapPoint(Convert.ToDouble(x), Convert.ToDouble(y));
                        x = coor[0];
                        y = coor[1];
                        MapPoint mp2 = new MapPoint(Convert.ToDouble(x), Convert.ToDouble(y));
                        //在地图中绘制点和轨迹
                        Dispatcher.BeginInvoke(() => { CreatPoint(mp2); });
                        Dispatcher.BeginInvoke(() => { CreatLine(mp1, mp2);});
                    }
                  //继续向服务器接收数据,注意不要关闭Socket连接
                    socket.ReceiveAsync(e); 
                }
            }
    复制代码

    在地图上添加点和线的方法

    复制代码
        private void CreatPoint(MapPoint mp)
           {
               Graphic g = new Graphic()
               {
                   Symbol = new SimpleMarkerSymbol()
                   {
                       Size = 18,
                       Color = new SolidColorBrush(Colors.Blue),
                       Style = SimpleMarkerSymbol.SimpleMarkerStyle.Circle
                   },
                   Geometry = mp
               };
               graphiclayer.Graphics.Clear();
               graphiclayer.Graphics.Add(g);
           }
    
           private void CreatLine(MapPoint mp1,MapPoint mp2)
           {
               ESRI.ArcGIS.Client.Geometry.Polyline pl = new ESRI.ArcGIS.Client.Geometry.Polyline();
               ESRI.ArcGIS.Client.Geometry.PointCollection pc = new ESRI.ArcGIS.Client.Geometry.PointCollection();
               pc.Add(mp1);
               pc.Add(mp2);
               pl.Paths.Add(pc);
               Graphic g = new Graphic()
               {
                   Symbol=LayoutRoot.Resources["LineSymbol"] as SimpleLineSymbol,
                   Geometry = pl
               };
               routeLayer.Graphics.Add(g);
           }
    复制代码

    本文通过双击地图获得一个起始点坐标,并将该坐标发送给服务器,示例代码:

    复制代码
      private void MyMap_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
            {
                MapPoint mp = e.MapPoint;
                x = mp.X.ToString ("#0.00");
                y = mp.Y.ToString ("#0.00");
                Graphic g = new Graphic()
                {
                    Symbol = new SimpleMarkerSymbol()
                    {
                        Size=9,
                        Color=new SolidColorBrush(Colors.Blue),
                        Style=SimpleMarkerSymbol.SimpleMarkerStyle.Circle
                    },
                    Geometry=mp
                };
                graphiclayer.Graphics.Add(g);
                MessageTextBox.Text = x + "|" + y;
            }
    复制代码

    关于其他部分的代码,例如声明图层,情况列表再次不再强调,具体请看下面代码:

    MainPage.cs

    View Code
    复制代码
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Net;
      5 using System.Windows;
      6 using System.Windows.Controls;
      7 using System.Windows.Documents;
      8 using System.Windows.Input;
      9 using System.Windows.Media;
     10 using System.Windows.Media.Animation;
     11 using System.Windows.Shapes;
     12 using System.Net.Sockets;
     13 using System.Text;
     14 using ESRI.ArcGIS.Client;
     15 using ESRI.ArcGIS.Client.Geometry;
     16 using ESRI.ArcGIS.Client.Symbols;
     17 using ESRI.ArcGIS.Client.Tasks;
     18 namespace SilverlightSocket
     19 {
     20     public partial class MainPage : UserControl
     21     {
     22         private Socket socket;
     23         private string x, y;
     24         GraphicsLayer graphiclayer;
     25         GraphicsLayer routeLayer;
     26         public MainPage()
     27         {
     28             InitializeComponent();
     29             SendButton.Click += new RoutedEventHandler(SendButton_Click);
     30             ClearButton.Click += ClearButton_Click;
     31             MyMap.MouseClick+=MyMap_MouseClick;
     32             graphiclayer = MyMap.Layers["GraphicLayer"] as GraphicsLayer;
     33             routeLayer = MyMap.Layers["routeLayer"] as GraphicsLayer;
     34         }
     35 
     36         private void MyMap_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
     37         {
     38             MapPoint mp = e.MapPoint;
     39             x = mp.X.ToString ("#0.00");
     40             y = mp.Y.ToString ("#0.00");
     41             Graphic g = new Graphic()
     42             {
     43                 Symbol = new SimpleMarkerSymbol()
     44                 {
     45                     Size=9,
     46                     Color=new SolidColorBrush(Colors.Blue),
     47                     Style=SimpleMarkerSymbol.SimpleMarkerStyle.Circle
     48                 },
     49                 Geometry=mp
     50             };
     51             graphiclayer.Graphics.Add(g);
     52             MessageTextBox.Text = x + "|" + y;
     53         }
     54 
     55         void ClearButton_Click(object sender, RoutedEventArgs e)
     56         {
     57             listBox1.Items.Clear();
     58         }
     59 
     60         private void SendButton_Click(object sender, RoutedEventArgs e)
     61         {
     62             if(string.IsNullOrEmpty(IPTextBox.Text)||string.IsNullOrEmpty(PortTextBox.Text))
     63             {
     64                 MessageBox.Show ("请输入主机IP地址和端口号!");
     65                 return;
     66             }
     67             //ip地址
     68             string host=IPTextBox.Text.Trim();
     69             //端口号
     70             int port=Convert.ToInt32(PortTextBox.Text.Trim());
     71             //建立终结点对象
     72             DnsEndPoint hostEntry=new DnsEndPoint(host,port);
     73             //创建一个Socket对象
     74             socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
     75             //创建Socket异步事件参数
     76             SocketAsyncEventArgs socketEventArg=new SocketAsyncEventArgs ();
     77             //将消息转化为发送的byte[]格式
     78             byte[]buffer=Encoding.UTF8.GetBytes(MessageTextBox.Text);
     79             //注册Socket完成事件
     80             socketEventArg.Completed+=new EventHandler<SocketAsyncEventArgs>(socketEventArg_Completed);
     81             //设置Socket异步事件远程终结点
     82             socketEventArg.RemoteEndPoint=hostEntry;
     83             //将定义好的Socket对象赋值给Socket异步事件参数的运行实例属性
     84             socketEventArg.UserToken = buffer;
     85             //socketEventArg.UserToken = socket;
     86             try
     87             {
     88                 socket.ConnectAsync(socketEventArg);
     89             }
     90             catch(SocketException ex)
     91             {
     92                 throw new SocketException((int)ex.ErrorCode);
     93             }
     94         }
     95 
     96        private void socketEventArg_Completed(object sender, SocketAsyncEventArgs e)
     97         {
     98            //检查是否发送出错
     99             if (e.SocketError != SocketError.Success)
    100             {
    101                 if (e.SocketError == SocketError.ConnectionAborted)
    102                 {
    103                     Dispatcher.BeginInvoke(() => MessageBox.Show("连接超时....请重试!"));
    104                 }
    105                 else if (e.SocketError == SocketError.ConnectionRefused)
    106                 {
    107                     Dispatcher.BeginInvoke(() => MessageBox.Show("无法连接到服务器端:"+e.SocketError));
    108                 }else
    109                 {
    110                     Dispatcher.BeginInvoke(() => MessageBox.Show("Socket连接已断开!"));
    111                 }
    112                 return;
    113             }
    114            //如果连接上,则发送数据
    115             if (e.LastOperation == SocketAsyncOperation.Connect)
    116             {
    117                     byte[] userbytes = (byte[])e.UserToken;
    118                     e.SetBuffer(userbytes, 0, userbytes.Length);
    119                     socket.SendAsync(e);
    120                     
    121             }//如果已发送数据,则开始接收服务器回复的消息
    122             else if (e.LastOperation == SocketAsyncOperation.Send)
    123             {
    124                 Dispatcher.BeginInvoke(() =>
    125                 {
    126                     listBox1.Items.Add("客户端在" + DateTime.Now.ToShortTimeString() + ",发送消息:" + MessageTextBox.Text);
    127                 });
    128                 byte[] userbytes = new byte[1024];
    129                 e.SetBuffer(userbytes, 0, userbytes.Length);
    130                 socket.ReceiveAsync(e);
    131             }//接收服务器数据
    132             else if (e.LastOperation == SocketAsyncOperation.Receive)
    133             {
    134                 string RecevieStr = Encoding.UTF8.GetString(e.Buffer, 0, e.Buffer.Length).Replace("\0", "");
    135                 Dispatcher.BeginInvoke(() =>
    136                 {
    137                     listBox1.Items.Add("服务器在" + DateTime.Now.ToShortTimeString() + ",回复消息:" + RecevieStr);
    138                 });
    139                 if (RecevieStr.Contains("|"))
    140                 {
    141                     string[] coor = RecevieStr.Split('|');
    142                     MapPoint mp1 = new MapPoint(Convert.ToDouble(x), Convert.ToDouble(y));
    143                     x = coor[0];
    144                     y = coor[1];
    145                     MapPoint mp2 = new MapPoint(Convert.ToDouble(x), Convert.ToDouble(y));
    146                     Dispatcher.BeginInvoke(() => { CreatPoint(mp2); });
    147                     Dispatcher.BeginInvoke(() => { CreatLine(mp1, mp2);});
    148                 }
    149                 socket.ReceiveAsync(e); 
    150             }
    151         }
    152 
    153        private void CreatPoint(double x,double y)
    154        {
    155            MapPoint mp = new MapPoint(x, y);
    156            Graphic g = new Graphic()
    157            {
    158                Symbol = new SimpleMarkerSymbol()
    159                {
    160                    Size = 18,
    161                    Color = new SolidColorBrush(Colors.Blue),
    162                    Style = SimpleMarkerSymbol.SimpleMarkerStyle.Circle
    163                },
    164                Geometry = mp
    165            };
    166            graphiclayer.Graphics.Clear();
    167            graphiclayer.Graphics.Add(g);
    168        }
    169 
    170        private void CreatPoint(MapPoint mp)
    171        {
    172            Graphic g = new Graphic()
    173            {
    174                Symbol = new SimpleMarkerSymbol()
    175                {
    176                    Size = 18,
    177                    Color = new SolidColorBrush(Colors.Blue),
    178                    Style = SimpleMarkerSymbol.SimpleMarkerStyle.Circle
    179                },
    180                Geometry = mp
    181            };
    182            graphiclayer.Graphics.Clear();
    183            graphiclayer.Graphics.Add(g);
    184        }
    185 
    186        private void CreatLine(MapPoint mp1,MapPoint mp2)
    187        {
    188            ESRI.ArcGIS.Client.Geometry.Polyline pl = new ESRI.ArcGIS.Client.Geometry.Polyline();
    189            ESRI.ArcGIS.Client.Geometry.PointCollection pc = new ESRI.ArcGIS.Client.Geometry.PointCollection();
    190            pc.Add(mp1);
    191            pc.Add(mp2);
    192            pl.Paths.Add(pc);
    193            Graphic g = new Graphic()
    194            {
    195                Symbol=LayoutRoot.Resources["LineSymbol"] as SimpleLineSymbol,
    196                Geometry = pl
    197            };
    198            routeLayer.Graphics.Add(g);
    199        }
    200 
    201        private void StopButton_Click_1(object sender, RoutedEventArgs e)
    202        {
    203            if (socket != null)
    204                socket.Shutdown(SocketShutdown.Both);
    205            socket.Close();
    206        }
    207     }
    208 }
    复制代码

    MainPage.xaml

    复制代码
    <UserControl
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:esri="http://schemas.esri.com/arcgis/client/2009" x:Class="SilverlightSocket.MainPage"
        mc:Ignorable="d">
    
        <Grid x:Name="LayoutRoot" Background="White" Width="900">
            <Grid.Resources>
                <esri:SimpleLineSymbol x:Key="LineSymbol" Color="Red" Style="Solid" Width="3"/>
            </Grid.Resources>
                
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.868*"/>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <esri:Map x:Name="MyMap" Background="White" WrapAround="True" Grid.ColumnSpan="2">
                <esri:ArcGISTiledMapServiceLayer Url="http://www.arcgisonline.cn/ArcGIS/rest/services/ChinaOnlineStreetColor/MapServer"/>
                <esri:GraphicsLayer ID="routeLayer"/>
                <esri:GraphicsLayer ID="GraphicLayer"/>
            </esri:Map>
            <StackPanel Grid.Column="1" Background="#7F094870">
                <StackPanel.Effect>
                    <DropShadowEffect/>
                </StackPanel.Effect>
                <TextBlock x:Name="textBlock1" Text="主机IP" Grid.Column="1" Margin="5,5,0,0" Foreground="#FFE7D4E3" FontWeight="Bold" />
                <TextBox x:Name="IPTextBox" Text="169.254.57.67" Grid.Column="1" d:LayoutOverrides="Width" Margin="5,5,0,0" HorizontalAlignment="Left"/>
                <TextBlock x:Name="textBlock2" Text="端口号" Grid.Column="1" Margin="5,5,0,0" Foreground="#FFE7D4E3" FontWeight="Bold" />
                <TextBox x:Name="PortTextBox" Width="51" Text="4530" Grid.Column="1" Margin="5,5,0,0" HorizontalAlignment="Left"/>
                <TextBlock  x:Name="textBlock4" Text="消息记录:" Height="23" Grid.Column="1" Margin="5,5,0,0" Foreground="#FFE7D4E3" FontWeight="Bold" />
                <ListBox  x:Name="listBox1" Grid.Column="1" Margin="5,5,0,0" Height="200" />
                <TextBlock x:Name="textBlock3" Text="发送信息内容" Height="16" Grid.Column="1" d:LayoutOverrides="Width" Margin="5,5,0,0" Foreground="#FFE7D4E3" FontWeight="Bold" VerticalAlignment="Bottom" />
                <TextBox x:Name="MessageTextBox" Grid.Column="1" Height="50" Margin="5,5,0,0" VerticalAlignment="Bottom" />
                <Button Content="发送" Height="23" x:Name="SendButton" Grid.Column="1" Margin="5,5,0,0" VerticalAlignment="Bottom" />
                <Button Content="清空" Height="23" x:Name="ClearButton" Grid.Column="1" Margin="5,5,0,0" VerticalAlignment="Bottom" />
                <Button Content="停止" Height="23" x:Name="StopButton" Grid.Column="1" Margin="5,5,0,0" VerticalAlignment="Bottom" Click="StopButton_Click_1" />
            </StackPanel>
            <esri:ScaleLine HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="30,0,0,20" Map="{Binding ElementName=MyMap}"/>
        </Grid>
    </UserControl>
    复制代码

    最后的效果:

    服务器端:

    客户端:

    由于是图片,所以无法预览动态绘制的效果,只能看图片了。

    (版权所有,转载请标明出处)

  • 相关阅读:
    php intval()函数
    MVC开发模式
    Session详解
    JSP入门
    Response中文乱码问题
    cookie入门
    idea实现更改servlet模板
    使用new和newInstance()创建类的区别
    Servlet 3.0 新特性详解
    web Servlet 3.0 新特性之web模块化编程,web-fragment.xml编写及打jar包
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/2880824.html
Copyright © 2020-2023  润新知