来源: http://kb.cnblogs.com/a/2098632/
写在最前:以前在C\C++控制台,简单MFC和C#程序里简单接触了网络套接字编程。了解了网络套接字是这样一个流程 打开 -> 发送/接收->关闭 的简单过程。由于网络传输速度影响,在网络套接字的同步调用时会对程序的使用性产生影响(程序界面被卡死),后来知道可以使用异步编程的概念——通过开线程来达到不阻塞用户界面的效果。后来在接触网络套接字编程的次数多了以后,在C#.NET环境中发现Socket竟然多出了两类方法 XXXXAsync 和 BeginXXXX / EndXXXX。接下来就用代码演示一下这两类方法如何使用~
接下来的页面会很长,能扯一点的现在这扯一点。这两类方法分别对应SocketAsyncEventArgs 、 IAsyncResult。我暂时也讲不出什么,有问题问吧还是。文章最后有如何在vs一个解决方案中调试启动多个项目(这可能是很多人没有注意到的操作)。
So long,Coding
首先是XXXXAsync的,
Server
02 | using System.Collections.Generic; |
04 | using System.Net.Sockets; |
11 | static void Main( string [] args) |
13 | Socket serverSk = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
15 | serverSk.Bind( new IPEndPoint(IPAddress.Parse( "127.0.0.1" ), 8596)); |
18 | SocketAsyncEventArgs AcceptSAE = new SocketAsyncEventArgs(); |
19 | AcceptSAE.Completed += new EventHandler<SOCKETASYNCEVENTARGS>(AcceptSAE_Completed); |
20 | serverSk.AcceptAsync(AcceptSAE); |
25 | static void AcceptSAE_Completed( object sender, SocketAsyncEventArgs e) |
27 | Socket serverSk = sender as Socket; |
28 | if (e.SocketError == SocketError.Success) |
30 | serverSk = e.AcceptSocket; |
31 | SocketAsyncEventArgs SendSAE = new SocketAsyncEventArgs(); |
32 | byte [] data = System.Text.Encoding.UTF8.GetBytes( "OK,Just Put IT!" ); |
33 | SendSAE.SetBuffer(data, 0, data.Length); |
34 | SendSAE.Completed += new EventHandler<SOCKETASYNCEVENTARGS>(SendSAE_Completed); |
36 | SocketAsyncEventArgs RecieveSAE = new SocketAsyncEventArgs(); |
37 | byte [] buffer = new byte [2048]; |
38 | RecieveSAE.SetBuffer(buffer, 0, buffer.Length); |
39 | RecieveSAE.Completed += new EventHandler<SOCKETASYNCEVENTARGS>(RecieveSAE_Completed); |
41 | serverSk.ReceiveAsync(RecieveSAE); |
42 | serverSk.SendAsync(SendSAE); |
45 | Console.WriteLine( "接受网络套接字连接请求失败!具体原因请自己调试!" ); |
49 | static void RecieveSAE_Completed( object sender, SocketAsyncEventArgs e) |
51 | Socket sk = sender as Socket; |
52 | byte [] data = e.Buffer; |
53 | string msg = System.Text.Encoding.UTF8.GetString(data); |
54 | Console.WriteLine( "Message received: " + msg); |
59 | static void SendSAE_Completed( object sender, SocketAsyncEventArgs e) |
61 | Socket sk = sender as Socket; |
62 | if (e.SocketError == SocketError.Success) |
64 | Console.WriteLine( "Send complete!" ); |
67 | byte [] data = e.Buffer; |
68 | string msg = System.Text.Encoding.UTF8.GetString(data); |
69 | Console.WriteLine( "What you sent: " + msg); |
73 | }</SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS> |
Client:
02 | using System.Collections.Generic; |
04 | using System.Net.Sockets; |
11 | static void Main( string [] args) |
13 | Socket clientSk = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
15 | SocketAsyncEventArgs ConnectSAE = new SocketAsyncEventArgs(); |
16 | ConnectSAE.RemoteEndPoint = new IPEndPoint(IPAddress.Parse( "127.0.0.1" ), 8596); |
17 | ConnectSAE.Completed += new EventHandler<SOCKETASYNCEVENTARGS>(ConnectSAE_Completed); |
18 | clientSk.ConnectAsync(ConnectSAE); |
22 | static void ConnectSAE_Completed( object sender, SocketAsyncEventArgs e) |
24 | Socket clientSk = sender as Socket; |
25 | if (e.SocketError == SocketError.Success && clientSk.Connected) |
27 | SocketAsyncEventArgs SendSAE = new SocketAsyncEventArgs(); |
28 | byte [] data = System.Text.Encoding.UTF8.GetBytes( "I want put all funy things together!" ); |
29 | SendSAE.SetBuffer(data, 0, data.Length); |
30 | SendSAE.Completed += new EventHandler<SOCKETASYNCEVENTARGS>(SendSAE_Completed); |
32 | SocketAsyncEventArgs RecieveSAE = new SocketAsyncEventArgs(); |
33 | byte [] buffer = new byte [2048]; |
34 | RecieveSAE.SetBuffer(buffer, 0, buffer.Length); |
35 | RecieveSAE.Completed += new EventHandler<SOCKETASYNCEVENTARGS>(RecieveSAE_Completed); |
38 | clientSk.ReceiveAsync(RecieveSAE); |
39 | clientSk.SendAsync(SendSAE); |
43 | static void RecieveSAE_Completed( object sender, SocketAsyncEventArgs e) |
45 | Socket sk = sender as Socket; |
46 | byte [] data = e.Buffer; |
47 | string msg = System.Text.Encoding.UTF8.GetString(data); |
48 | Console.WriteLine( "Message received: " +msg); |
53 | static void SendSAE_Completed( object sender, SocketAsyncEventArgs e) |
55 | Socket sk = sender as Socket; |
56 | if (e.SocketError == SocketError.Success) |
58 | Console.WriteLine( "Send complete!" ); |
64 | }</SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS> |
然后是BenginXXXX 和 EndXXXX的
Server
002 | using System.Collections.Generic; |
004 | using System.Net.Sockets; |
013 | private Socket _Socket; |
014 | private string _MyName = "" ; |
015 | private byte [] _Buffer; |
024 | get { return _Socket; } |
025 | set { _Socket = value; } |
031 | get { return _Buffer; } |
032 | set { _Buffer = value; } |
038 | get { return _MyName; } |
039 | set { _MyName = value; } |
046 | public MyObject(Socket socket, string myName) |
051 | public MyObject(Socket socket, string myName, byte [] buffer) |
063 | static void Main( string [] args) |
065 | Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
067 | server.Bind( new IPEndPoint(IPAddress.Parse( "127.0.0.1" ), 8596)); |
070 | server.BeginAccept( new AsyncCallback(AcceptComplete), new MyObject(server, "开始连接了" )); |
077 | static void AcceptComplete(IAsyncResult ar) |
079 | MyObject myObj = ar.AsyncState as MyObject; |
080 | Socket serverSk = myObj.Socket.EndAccept(ar); |
082 | byte [] buffer = new byte [2048]; |
084 | serverSk.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecievedComplete), new MyObject(serverSk, "开始接收了" , buffer)); |
086 | byte [] datas = System.Text.Encoding.UTF8.GetBytes( "I know , Just put it!" ); |
087 | serverSk.BeginSend(datas, 0, datas.Length, SocketFlags.None, new AsyncCallback(SendComplete), new MyObject(serverSk, "开始发送了" , datas)); |
091 | static void SendComplete(IAsyncResult ar) |
093 | MyObject myObj = ar.AsyncState as MyObject; |
094 | Socket sk = myObj.Socket; |
096 | int sended = sk.EndSend(ar); |
098 | Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer)); |
101 | static void RecievedComplete(IAsyncResult ar) |
104 | MyObject myObj = ar.AsyncState as MyObject; |
105 | Socket sk = myObj.Socket; |
107 | int recieved = sk.EndReceive(ar); |
109 | Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer)); |
Client
002 | using System.Collections.Generic; |
004 | using System.Net.Sockets; |
013 | private Socket _Socket; |
014 | private string _MyName = "" ; |
015 | private byte [] _Buffer; |
024 | get { return _Socket; } |
025 | set { _Socket = value; } |
031 | get { return _Buffer; } |
032 | set { _Buffer = value; } |
038 | get { return _MyName; } |
039 | set { _MyName = value; } |
046 | public MyObject(Socket socket, string myName) |
051 | public MyObject(Socket socket, string myName, byte [] buffer) |
063 | static void Main( string [] args) |
065 | Socket clientSk = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
067 | clientSk.BeginConnect( new IPEndPoint(IPAddress.Parse( "127.0.0.1" ), 8596), new AsyncCallback(ConnectComplete), new MyObject(clientSk, "开始连接了" )); |
073 | static void ConnectComplete(IAsyncResult ar) |
075 | MyObject myObj = ar.AsyncState as MyObject; |
076 | Socket clientSk = myObj.Socket; |
078 | byte [] datas = System.Text.Encoding.UTF8.GetBytes( "I always want put things together!" ); |
079 | clientSk.BeginSend(datas, 0, datas.Length, SocketFlags.None, new AsyncCallback(SendComplete), new MyObject(clientSk, "开始发送了" , datas)); |
082 | byte [] buffer = new byte [2048]; |
084 | clientSk.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecievedComplete), new MyObject(clientSk, "开始接收了" , buffer)); |
088 | static void SendComplete(IAsyncResult ar) |
090 | MyObject myObj = ar.AsyncState as MyObject; |
091 | Socket sk = myObj.Socket; |
093 | int sended = sk.EndSend(ar); |
095 | Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer)); |
098 | static void RecievedComplete(IAsyncResult ar) |
101 | MyObject myObj = ar.AsyncState as MyObject; |
102 | Socket sk = myObj.Socket; |
104 | int recieved = sk.EndReceive(ar); |
106 | Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer)); |
The end.
附:
启动第一个项目
启动第二个...第N个