Silverlight2调用Socket完整代码

来源:互联网 发布:怎样注册开淘宝网店 编辑:程序博客网 时间:2024/05/01 03:49

1。 建立Silverlight项目,选择“add a new web to the solution...”,添加Socket Helper Class:

NetWorking.cs:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace SilverlightSocket
{
    internal sealed class SocketClient : IDisposable
    {
        private const int Receive = 1;
        private const int Send = 0;

        private bool isConnected = false;

        private Socket socket;
        private DnsEndPoint endPoint;
        private IPEndPoint z;

        private static AutoResetEvent autoEvent = new AutoResetEvent(false);
        private static AutoResetEvent[] autoSendReceiveEvents = new AutoResetEvent[]
                {
                        new AutoResetEvent(false),
                        new AutoResetEvent(false)
                };

        internal SocketClient(string host, int port)
        {
            z = new IPEndPoint(IPAddress.Parse(host), port);
            endPoint = new DnsEndPoint(host, port);
            socket = new Socket(AddressFamily.InterNetwork
                /* hostEndPoint.AddressFamily */,
                        SocketType.Stream, ProtocolType.Tcp);
        }

        internal void Connect()
        {
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();

            args.UserToken = socket;
            args.RemoteEndPoint = z;
            args.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);

            socket.ConnectAsync(args);
            autoEvent.WaitOne();

            if (args.SocketError != SocketError.Success)
                throw new SocketException((int)args.SocketError);
        }

        internal void Disconnect()
        {
            socket.Close();
        }

        #region Events

        private void OnConnect(object sender, SocketAsyncEventArgs e)
        {
            autoEvent.Set();
            isConnected = (e.SocketError == SocketError.Success);
        }

        private void OnReceive(object sender, SocketAsyncEventArgs e)
        {
            autoSendReceiveEvents[Send].Set();
        }

        private void OnSend(object sender, SocketAsyncEventArgs e)
        {
            autoSendReceiveEvents[Receive].Set();

            if (e.SocketError == SocketError.Success)
            {
                if (e.LastOperation == SocketAsyncOperation.Send)
                {
                    // Prepare receiving.
                    Socket s = e.UserToken as Socket;

                    byte[] response = new byte[255];
                    e.SetBuffer(response, 0, response.Length);
                    e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
                    s.ReceiveAsync(e);
                }
            }
            else
            {
                ProcessError(e);
            }
        }

        #endregion

        private void ProcessError(SocketAsyncEventArgs e)
        {
            Socket s = e.UserToken as Socket;
            if (s.Connected)
            {
                try
                {
                    s.Shutdown(SocketShutdown.Both);
                }
                catch (Exception)
                {
                }
                finally
                {
                    if (s.Connected)
                        s.Close();
                }
            }

            throw new SocketException((int)e.SocketError);
        }

        internal String SendReceive(string message)
        {
            if (isConnected)
            {
                Byte[] bytes = Encoding.UTF8.GetBytes(message);

                SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                args.SetBuffer(bytes, 0, bytes.Length);
                args.UserToken = socket;
                args.RemoteEndPoint = endPoint;
                args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);

                socket.SendAsync(args);

                AutoResetEvent.WaitAll(autoSendReceiveEvents);

                return Encoding.UTF8.GetString(args.Buffer, args.Offset, args.BytesTransferred);
            }
            else
                throw new SocketException((int)SocketError.NotConnected);
        }

        #region IDisposable Members

        public void Dispose()
        {
            autoEvent.Close();
            autoSendReceiveEvents[Send].Close();
            autoSendReceiveEvents[Receive].Close();
            if (socket.Connected)
                socket.Close();
        }

        #endregion
    }
}

在Page.xaml上简单加一个TextBlock用于显示返回字符串,后台文件内容:

...public Page()
        {
            InitializeComponent();

            string host = "127.0.0.1"; //这里本应该是服务器的IP地址,但由于安全原因,目前似乎不可以写成绝对IP地址如:10.235.32.155等。
            SocketClient sc = new SocketClient(host, 4522);
            sc.Connect();
            string z = sc.SendReceive("test");
            this.ScTxt.Text = z;// System.Windows.Application.Current.Host.Source.Host;
            sc.Disconnect(); // 记得不用的时候要断开连接,否则当页面刷新时会产生IOException
        }...

2。 服务器端:

建立服务器侦听程序:

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

class MyTcpListener
{
    public static void Main()
    {
        TcpListener server = null;
        try
        {
            // Set the TcpListener on port 4522.
            Int32 port = 4522;
            IPAddress localAddr = IPAddress.Parse("127.0.0.1"); // 同上

            // TcpListener server = new TcpListener(port);
            server = new TcpListener(localAddr, port);

            // Start listening for client requests.
            server.Start();

            // Buffer for reading data
            Byte[] bytes = new Byte[256];
            String data = null;

            // Enter the listening loop.
            while (true)
            {
                Console.Write("Waiting for a connection... ");

                // Perform a blocking call to accept requests.
                // You could also user server.AcceptSocket() here.
                TcpClient client = server.AcceptTcpClient();
                Console.WriteLine("Connected!");

                data = null;

                // Get a stream object for reading and writing
                NetworkStream stream = client.GetStream();

                int i;

                // Loop to receive all the data sent by the client.
                while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                {
                    // Translate data bytes to a ASCII string.
                    data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                    Console.WriteLine("Received: {0}", data);

                    // Process the data sent by the client.
                    data = data.ToUpper();

                    byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

                    // Send back a response.
                    stream.Write(msg, 0, msg.Length);
                    Console.WriteLine("Sent: {0}", data);
                }
                Console.WriteLine("Client close.");
                // Shutdown and end connection
                client.Close();
            }
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
        }
        catch (System.IO.IOException ex)
        {
            Console.WriteLine("IOException: {0}", ex);
        }
        finally
        {
            // Stop listening for new clients.
            server.Stop();
        }

        Console.WriteLine("/nHit enter to continue...");
        Console.Read();
    }
}

3。 运行服务器。

运行第2步中的应用程序。第1次运行时,如果防火墙开启的话,可能会询问是否解除对此进程的阻止,点“解除阻止”。随即打开命令行界面,显示Waiting for a connection...

4。 运行客户端,浏览Silverlight项目中测试页面,显示正确结果TEST。

 

Socket Helper Class:http://weblogs.asp.net/mschwarz/archive/2008/03/07/silverlight-2-and-sockets.aspx