说明:
作者:敖士伟
一、客户端收发类为SocketAsyncClient
1、构造函数SocketAsyncClient(string ip, Int32 port)初始远程主机IP和端口;
2、方法SendMsg(string msg)异步发送消息;
3、委托事件ReceiveMSGEvent接收回发消息。
二、使用此类的方法注册接收回发事件
SocketAsyncClient sac = new SocketAsyncClient("192.168.0.37", 7777); sac.ReceiveMSGEvent += GetReceiveMSG; sac.SendMsg(textBox1.Text); void GetReceiveMSG(string msg){ //下面一行避免出现:线程间操作无效: 从不是创建控件 的线程访问它 Control.CheckForIllegalCrossThreadCalls = false; label1.Text=msg; }
类:
/// <summary> /// 异步“发送--接收”Socket类。作者:敖士伟 Email:[email protected] /// </summary> public class SocketAsyncClient { //-------属性开始 /// <summary> /// 发送/接收套节字 /// </summary> private Socket SendSocket; /// <summary> /// 网络端点( IP 地址和端口号) /// </summary> private IPEndPoint hostEndPoint; /// <summary> /// 异步对象上下文 /// </summary> private SocketAsyncEventArgs SendEventArg; /// <summary> /// 到回发消息委托 /// </summary> /// <param name="msg">回发消息</param> public delegate void ReceiveMSGHandler(string msg); /// <summary> /// 到回发消息事件 /// </summary> public event ReceiveMSGHandler ReceiveMSGEvent; //-------属性结束 internal SocketAsyncClient(string ip, Int32 port) { this.hostEndPoint = new IPEndPoint(IPAddress.Parse(ip), port); this.SendSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); this.SendSocket.Connect(hostEndPoint); } /// <summary> /// 发送消息 /// </summary> /// <param name="msg">消息</param> public void SendMsg(string msg) { if (SendEventArg == null) { SendEventArg = new SocketAsyncEventArgs(); //发送缓存 Byte[] sendBuffer = Encoding.UTF8.GetBytes(msg); SendEventArg.SetBuffer(sendBuffer, 0, sendBuffer.Length); SendEventArg.UserToken = this.SendSocket; SendEventArg.RemoteEndPoint = this.hostEndPoint; //异步接收请求回调 SendEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(OnSendCompleted); } else { //重用异步对象上下文时消除其socket SendEventArg.AcceptSocket = null; } //开始异步发送 Boolean willRaiseEvent = this.SendSocket.SendAsync(SendEventArg); //同步完成 if (!willRaiseEvent) { this.OnSendCompleted(null, SendEventArg); } } /// <summary> /// 发送完成回调 /// </summary> /// <param name="sender"></param> /// <param name="e">异步对象上下文</param> private void OnSendCompleted(object sender, SocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { if (e.LastOperation == SocketAsyncOperation.Send) { // 准备接收 Socket s = e.UserToken as Socket; //接收缓存 byte[] receiveBuffer = new byte[255]; e.SetBuffer(receiveBuffer, 0, receiveBuffer.Length); //接收完成回调 e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceiveCompleted); //开始异步接收 Boolean willRaiseEvent = s.ReceiveAsync(e); if (!willRaiseEvent) { this.OnReceiveCompleted(null, e); } } } else { this.CloseClientSocket(e); } } /// <summary> /// 接收完成回调 /// </summary> /// <param name="sender"></param> /// <param name="e">异步对象上下文</param> private void OnReceiveCompleted(object sender, SocketAsyncEventArgs e) { // 检查远程主机是否断开 if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { Socket s = e.UserToken as Socket; Int32 bytesTransferred = e.BytesTransferred; // Get the message received from the listener. String received = Encoding.UTF8.GetString(e.Buffer, e.Offset, bytesTransferred); //得到回发消息事件 ReceiveMSGEvent(received); } else { this.CloseClientSocket(e); } } /// <summary> /// 关闭socket /// </summary> /// <param name="e">异步对象上下文</param> private void CloseClientSocket(SocketAsyncEventArgs e) { Socket s = e.UserToken as Socket; try { s.Shutdown(SocketShutdown.Send); } catch (Exception ex) { s.Close(); throw ex; } s.Close(); } }