代码
C# Socket异步通讯是如何实现的呢?C# Socket异步通讯客户端设计的思路是什么呢?那么本文就向你介绍具体的内容。
C# Socket异步通讯客户端实现源码

C# Socket异步通讯客户端之主程序:

public static int Main(String[] args) { IPAddress ipAddress = IPAddress.Parse("192.168.1.104"); int port = 20000; IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); // 生成一个TCP/IP socket. Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 与目标终端连接. client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); //等待,直到连接程序完成。在ConnectCallback中适当位置有connecDone.Set()语句 connectDone.WaitOne(); // 发送数据到远程终端. Send(client, "This is a test<EOF>"); sendDone.WaitOne(); // 接收返回数据. Receive(client); receiveDone.WaitOne(); // Write the response to the console. Console.WriteLine("Response received : {0}", response); // Release the socket. client.Shutdown(SocketShutdown.Both); client.Close(); return 0; } C# Socket异步通讯客户端之连接部分Callback:

private static void ConnectCallback(IAsyncResult ar) { // 从state对象获取socket. Socket client = (Socket)ar.AsyncState; // 完成连接. client.EndConnect(ar); Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString()); // 连接已完成,主线程继续. connectDone.Set(); } C# Socket异步通讯客户端之数据接收:

private static void Receive(Socket client) { // 构造容器state. StateObject state = new StateObject(); state.workSocket = client; // 从远程目标接收数据. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } private static void ReceiveCallback(IAsyncResult ar) { // 从输入参数异步state对象中获取state和socket对象 StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; //从远程设备读取数据 int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { // 有数据,存储. state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); // 继续读取. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } else { // 所有数据读取完毕. if (state.sb.Length > 1) { response = state.sb.ToString(); } // 所有数据读取完毕的指示信号. receiveDone.Set(); } } C# Socket异步通讯客户端之发送数据:

private static void Send(Socket client, String data) { // 格式转换. byte[] byteData = Encoding.ASCII.GetBytes(data); // 开始发送数据到远程设备. client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); } private static void SendCallback(IAsyncResult ar) { // 从state对象中获取socket Socket client = (Socket)ar.AsyncState; // 完成数据发送. int bytesSent = client.EndSend(ar); Console.WriteLine("Sent {0} bytes to server.", bytesSent); // 指示数据已经发送完成,主线程继续. sendDone.Set(); } C# Socket异步通讯客户端的实现源码内容就基本向你介绍到这里,希望对你了解和学习C# Socket异步通讯有所帮助。

 

代码
以SOCKET通信中的异步方法为例:

public static ManualResetEvent ConnectDone = new ManualResetEvent(false);

public static void ConnectCallback(IAsyncResult ar)

{

Socket sClient
= (Socket)ar.AsyncState;



sClient.EndConnect(ar);



Console.WriteLine(
"Socket connected to {0}", sClient.RemoteEndPoint.ToString());

ConnectDone.Set();

}

public static void Main(string[] arg)

{

try

{

IPHostEntry ipHost
= Dns.Resolve("127.0.0.1");

IPAddress ipAddr
= ipHost.AddressList[0];

IPEndPoint endPoint
= new IPEndPoint(ipAddr, 11000);



Socket sClient
= new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);



sClient.BeginConnect(endPoint,
new AsyncCallback(ConnectCallback),

sClient);



for (int i = 0; i <5; i++)

Console.WriteLine(
"Do Some Other Work.");



byte[] byteData = Encoding.ASCII.GetBytes("Some Data.");



ConnectDone.WaitOne();



sClient.BeginSend(byteData,
0, byteData.Length, 0,

new AsyncCallback(SendCallback), sClient);



………

}

(注:ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。

ManualResetEvent就像一个信号灯,可以利用它的信号来通知其它线程。它有几个重要的方法:Reset(),Set(),WaitOne()。初始化该对象时,用户可以指定其默认的状态(有信号
/无信号),在初始化以后,该对象将保持原来的状态不变直到它的Reset()或者Set()方法被调用,Reset()方法将其设置为无信号状态,Set()方法将其设置为有信号状态。WaitOne()方法使当前线程挂起直到ManualResetEvent对象处于有信号状态,此时该线程将被激活。)

本例中,主线程调用ConnectDone.WaitOne();后,主线程阻塞,直到连接操作(即 ConnectCallback)完成,因为连接操作完成之后,执行了ConnectDone.Set()将信号灯设置为有信号,由于调用了 ManualResetEvent.WaitOne()方法而处在等待状态的主线程将接收到这个信号,于是它接着往下执行,完成后边的工作。

同步与异步:

简单地说,同步即程序执行一个方法,等该方法返回之后,继续往下走,

异步:即程序调用一个方法后立即返回,“宏观”而言,主线程与方法线程并行执行。

就本例而言,socket的异步方法BeginConnect被调用后,接着执行主线程中该语句之后的代码,即:

for (int i = 0; i <5; i++)

Console.WriteLine(
"Do Some Other Work.");

byte[] byteData = Encoding.ASCII.GetBytes("Some Data.");

如果调用的是同步方法,那么,输出“Socket connected to…”一定会在“Do Some Other Work.”之前,因为主线程必须等待同步方法的返回,但是在异步的情况下,将可能在5行“Do Some Other Work.”之间的某个时刻出现“Socket connected to…”的输出(实际情况还依赖于操作系统的线程调度)。

至于在 sClient.BeginSend(…)方法之前调用ConnectDone.WaitOne(),则是由于前者依赖于连接操作(即 ConnectCallback)的完成,须得同步一下。

 

posted on 2010-04-08 02:42  sn_wolf  阅读(4392)  评论(1编辑  收藏  举报