客户端进行异步操作
接收信息及发送信息分开进行,运行多线程进行管理
主要代码发下:
using System;
using System.Collections.Generic;using System.Text;using System.Net.Sockets;using System.Threading;using System.Net;// 实现Socket客户端的连接通信逻辑。
internal sealed class SocketClient : IDisposable { // Socket操作常数。 private const Int32 ReceiveOperation = 1, SendOperation = 0; // 用于发送/接收消息的Socket。 private Socket clientSocket; // Socket连接标志。 private Boolean connected = false; // 侦听者端点。 private IPEndPoint hostEndPoint;//缓冲区大小
private int bufferSize = 2048;private int ReceiveBufferSize = 2096;
// 触发连接。
private static AutoResetEvent autoConnectEvent = new AutoResetEvent(false); // 触发发送/接收操作。 private static AutoResetEvent autoSendEvent = new AutoResetEvent(false); private static AutoResetEvent autoReceiveEvent = new AutoResetEvent(false); //private static AutoResetEvent[] autoSendReceiveEvents = new AutoResetEvent[] { new AutoResetEvent(false), new AutoResetEvent(false) }; // 创建一个未初始化的客户端实例。 // 启动传送/接收处理将调用Connect方法,然后是SendReceive方法。 internal SocketClient(String hostName, Int32 port) { // 获取主机有关的信息。 IPHostEntry host = Dns.GetHostEntry(hostName); // 主机地址。 IPAddress[] addressList = host.AddressList; // 实例化端点和Socket。 hostEndPoint = new IPEndPoint(addressList[addressList.Length - 1], port); clientSocket = new Socket(hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); }//得到连接服务器的状态
internal bool GetConnectState() { return connected; }// 连接主机(同步连接)。
internal void Connect() { try { clientSocket.Connect(hostEndPoint); this.connected = true; } catch (SocketException ex) { throw new Exception(ex.Message); } }//********* 以下为异步连接操作********
internal void ConnectAsync() { SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs(); connectArgs.UserToken = clientSocket; connectArgs.RemoteEndPoint = hostEndPoint; connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect); clientSocket.ConnectAsync(connectArgs); autoConnectEvent.WaitOne(); SocketError errorCode = connectArgs.SocketError; if (errorCode != SocketError.Success) { throw new SocketException((Int32)errorCode); } }// 与主机断开连接。
internal void Disconnect() { clientSocket.Disconnect(false); }// 连接操作的回调方法
private void OnConnect(object sender, SocketAsyncEventArgs e) { // 发出连接完成信号。 autoConnectEvent.Set(); // 设置Socket已连接标志。 connected = (e.SocketError == SocketError.Success);}
// 接收操作的回调方法 private void OnReceive(object sender, SocketAsyncEventArgs e) { // 发出接收完成信号。 //autoSendReceiveEvents[ReceiveOperation].Set(); autoReceiveEvent.Set();}
// 发送操作的回调方法 private void OnSend(object sender, SocketAsyncEventArgs e) { // 发出发送完成信号。 //autoSendReceiveEvents[SendOperation].Set(); autoSendEvent.Set(); //if (e.SocketError == SocketError.Success) //{ // if (e.LastOperation == SocketAsyncOperation.Send) // { // // 准备接收。 // Socket s = e.UserToken as Socket; // byte[] receiveBuffer = new byte[1024]; // e.SetBuffer(receiveBuffer, 0, receiveBuffer.Length); // e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive); // s.ReceiveAsync(e); // } //} //else //{ // ProcessError(e); //} } // 失败时关闭Socket,根据SocketError抛出异常。 private void ProcessError(SocketAsyncEventArgs e) { Socket s = e.UserToken as Socket; if (s.Connected) { // 关闭与客户端关联的Socket try { s.Shutdown(SocketShutdown.Both); } catch (Exception) { // 如果客户端处理已经关闭,抛出异常 } finally { if (s.Connected) { s.Close(); } } } // 抛出SocketException throw new SocketException((Int32)e.SocketError); } //接收消息 internal string FromHsMessage() { if (connected) { // 创建一个接收缓冲区。 byte[] receiveBuffer = new byte[ReceiveBufferSize]; // 准备发送/接收操作的参数。 SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs(); completeArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length); completeArgs.UserToken = clientSocket; completeArgs.RemoteEndPoint = hostEndPoint; completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive); // 开始异步接收。 clientSocket.ReceiveAsync(completeArgs); // 等待发送/接收完成。 autoReceiveEvent.WaitOne(); //AutoResetEvent.WaitAll(autoSendReceiveEvents); // 从SocketAsyncEventArgs缓冲区返回数据. return Encoding.UTF8.GetString(completeArgs.Buffer, completeArgs.Offset, completeArgs.BytesTransferred);}
else { throw new SocketException((Int32)SocketError.NotConnected); } }// 与主机交换消息(发送消息)。
internal String SendMessage(String message) { if (connected) { // 创建一个发送缓冲区。 Byte[] sendBuffer = Encoding.UTF8.GetBytes(message.ToCharArray(), 0, message.ToCharArray().Length); // 准备发送/接收操作的参数。 SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs(); completeArgs.SetBuffer(sendBuffer, 0, bufferSize > sendBuffer.Length ? sendBuffer.Length : bufferSize); completeArgs.UserToken = clientSocket; completeArgs.RemoteEndPoint = hostEndPoint; completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend); // 开始异步发送。 clientSocket.SendAsync(completeArgs); // 等待发送/接收完成。 autoSendEvent.WaitOne(); //AutoResetEvent.WaitAll(autoSendReceiveEvents); // 从SocketAsyncEventArgs缓冲区返回数据. return Encoding.UTF8.GetString(completeArgs.Buffer, completeArgs.Offset, completeArgs.BytesTransferred); } else { throw new SocketException((Int32)SocketError.NotConnected); } }#region IDisposable Members
// 释放SocketClient实例。 public void Dispose() { autoConnectEvent.Close(); autoSendEvent.Close(); autoReceiveEvent.Close(); //autoSendReceiveEvents[SendOperation].Close(); //autoSendReceiveEvents[ReceiveOperation].Close(); if (clientSocket.Connected) { clientSocket.Close(); } } #endregion }