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 System.Threading; using System.Net.Sockets; using System.Text; namespace SilverlightSoket { public partial class SoketTest : ChildWindow { public SoketTest() { InitializeComponent(); } private void OKButton_Click(object sender, RoutedEventArgs e) { soketServer.Mysocket.Send(Encoding.UTF8.GetBytes(textBox1.Text)); } private void CancelButton_Click(object sender, RoutedEventArgs e) { this.DialogResult = false; } } public class soketServer { public delegate void HandelShowInfo(string info,System.Net.Sockets.Socket e); public event HandelShowInfo EventShowInfo; //定义一个可在全局使用的Socket static soketServer m_mysocket; static System.Net.Sockets.Socket socket; static object m_lock=new object (); //定义一个同步上下文类,用来将子线程的操作调度到主线程上以可控制UI属性。 SynchronizationContext syn; /// <summary> /// 触发外部事件 /// </summary> /// <param name="info"></param> /// <param name="e"></param> void InvokeInfo(string info, System.Net.Sockets.Socket e) { if (this.EventShowInfo != null) this.EventShowInfo.Invoke(info, e); } static soketServer() { if (m_mysocket != null) return; lock (m_lock) { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_mysocket = new soketServer(); } } #region property public static soketServer Mysocket { get { return m_mysocket; } set { m_mysocket = value; } } #endregion public void Send(byte[] Content) { syn = SynchronizationContext.Current; //定义并实例一个Socket参数 SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs(); //设置到远程终节点属性(4502端口,为什么是4502,MS的SL通信安全上有) socketArgs.RemoteEndPoint = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, 4502); //设置好当Socket任何一个动作完成时的回调函数。 socketArgs.Completed += new EventHandler<SocketAsyncEventArgs>(socketArgs_Completed); //Socket参数的用户标识,实际上就是一个可以传递的OBJECT参数。 socketArgs.UserToken = Content; socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.ConnectAsync(socketArgs); } void socketArgs_Completed(object sender, SocketAsyncEventArgs e) { //当任何一个Socket动作完成,都回调该函数,然后对LastOperation进行判断后继续执行相应的部分 switch (e.LastOperation) { case SocketAsyncOperation.Connect: ProcessConnect(e); break; case SocketAsyncOperation.Receive: ProcessReceive(e); break; case SocketAsyncOperation.Send: ProcessSend(e); break; } } //将数据放入buffer并进行异步发送 void ProcessConnect(SocketAsyncEventArgs e) { //当连接成功后,获取Socket参数 e传递过来的用户标识(也就是本示例中用户输入的字符串转换的Byte字节数组) byte[] bytes = (byte[])e.UserToken; //设置Socket参数的缓冲区参数,将我们的字节数组设置为Socket的缓冲区。 e.SetBuffer(bytes, 0, bytes.Length); //同步一下上下文,显示一下当前的状态信息。 syn.Post(GetText, "States:" + e.SocketError.ToString() + "," + e.LastOperation.ToString()); //发送数据 socket.SendAsync(e); } //发送完成后,执行等待接收服务器发回的数据 void ProcessSend(SocketAsyncEventArgs e) { //定义个空的字节数组,设置好其大小 byte[] bytes = new byte[1024]; //将前面定义字节数组设置成缓冲区 e.SetBuffer(bytes, 0, bytes.Length); //执行异步接收 socket.ReceiveAsync(e); } //当接收完成后 void ProcessReceive(SocketAsyncEventArgs e) { //在执行好接收后,本地SOCKET的缓冲区就会被服务器发送的数据填充。 //显示下信息,当然也是用同步上下文的方式,在显示信息的时候,就直接将缓冲区的字节数组转换成字符串。 syn.Post(GetText, Encoding.UTF8.GetString(e.Buffer, 0, e.Buffer.Length) + " and Received"); //关闭Socket连接 socket.Close(); //最后显示下,Socket关闭。 syn.Post(GetText, "Socket Closed"); } //同步上下文调用的方法。 void GetText(object str) { MessageBox.Show(str.ToString()); } } }