C#Socket 异步代码示例

来源: http://kb.cnblogs.com/a/2098632/

写在最前:以前在C\C++控制台,简单MFC和C#程序里简单接触了网络套接字编程。了解了网络套接字是这样一个流程 打开 -> 发送/接收->关闭 的简单过程。由于网络传输速度影响,在网络套接字的同步调用时会对程序的使用性产生影响(程序界面被卡死),后来知道可以使用异步编程的概念——通过开线程来达到不阻塞用户界面的效果。后来在接触网络套接字编程的次数多了以后,在C#.NET环境中发现Socket竟然多出了两类方法 XXXXAsync 和 BeginXXXX / EndXXXX。接下来就用代码演示一下这两类方法如何使用~

    接下来的页面会很长,能扯一点的现在这扯一点。这两类方法分别对应SocketAsyncEventArgs  、 IAsyncResult。我暂时也讲不出什么,有问题问吧还是。文章最后有如何在vs一个解决方案中调试启动多个项目(这可能是很多人没有注意到的操作)。

So long,Coding

首先是XXXXAsync的,

  Server

 
01usingSystem;
02usingSystem.Collections.Generic;
03usingSystem.Text;
04usingSystem.Net.Sockets;
05usingSystem.Net;
06  
07namespaceSocketTest
08{
09    classProgram
10    {
11        staticvoidMain(string[] args)
12        {
13            Socket serverSk =newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
14  
15            serverSk.Bind(newIPEndPoint(IPAddress.Parse("127.0.0.1"), 8596));
16            serverSk.Listen(1);
17  
18            SocketAsyncEventArgs AcceptSAE =newSocketAsyncEventArgs();
19            AcceptSAE.Completed +=newEventHandler<SOCKETASYNCEVENTARGS>(AcceptSAE_Completed);
20            serverSk.AcceptAsync(AcceptSAE);
21  
22            Console.ReadLine();
23        }
24  
25        staticvoidAcceptSAE_Completed(objectsender, SocketAsyncEventArgs e)
26        {
27            Socket serverSk = senderasSocket;
28            if(e.SocketError == SocketError.Success)
29            {
30                serverSk = e.AcceptSocket;
31                SocketAsyncEventArgs SendSAE =newSocketAsyncEventArgs();
32                byte[] data = System.Text.Encoding.UTF8.GetBytes("OK,Just Put IT!");
33                SendSAE.SetBuffer(data, 0, data.Length);
34                SendSAE.Completed +=newEventHandler<SOCKETASYNCEVENTARGS>(SendSAE_Completed);
35  
36                SocketAsyncEventArgs RecieveSAE =newSocketAsyncEventArgs();
37                byte[] buffer =newbyte[2048];//因为我们不知道上面的字符串究竟会场生多少字节,这里我们就设置一个理论上可以满足大小的值2046。
38                RecieveSAE.SetBuffer(buffer, 0, buffer.Length);
39                RecieveSAE.Completed +=newEventHandler<SOCKETASYNCEVENTARGS>(RecieveSAE_Completed);
40  
41                serverSk.ReceiveAsync(RecieveSAE);
42                serverSk.SendAsync(SendSAE);
43            }
44            else
45                Console.WriteLine("接受网络套接字连接请求失败!具体原因请自己调试!");
46        }
47  
48  
49        staticvoidRecieveSAE_Completed(objectsender, SocketAsyncEventArgs e)
50        {
51            Socket sk = senderasSocket;
52            byte[] data = e.Buffer; //注意这里,如何取关联到套接字的发送接受的缓冲区中的值。
53            stringmsg = System.Text.Encoding.UTF8.GetString(data);
54            Console.WriteLine("Message received: "+ msg);
55  
56           // sk.DisconnectAsync();//你看看 该怎么做呢?
57        }
58  
59        staticvoidSendSAE_Completed(objectsender, SocketAsyncEventArgs e)
60        {
61            Socket sk = senderasSocket;
62            if(e.SocketError == SocketError.Success)
63            {
64                Console.WriteLine("Send complete!");
65  
66  
67                byte[] data = e.Buffer; //注意这里,如何取关联到套接字的发送接受的缓冲区中的值。
68                stringmsg = System.Text.Encoding.UTF8.GetString(data);
69                Console.WriteLine("What you sent: "+ msg);
70            }
71        }
72    }
73}</SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS>

Client:

 
01usingSystem;
02usingSystem.Collections.Generic;
03usingSystem.Text;
04usingSystem.Net.Sockets;
05usingSystem.Net;
06  
07namespaceSocketTestTwo
08{
09    classProgram
10    {
11        staticvoidMain(string[] args)
12        {
13            Socket clientSk =newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
14  
15            SocketAsyncEventArgs ConnectSAE =newSocketAsyncEventArgs();
16            ConnectSAE.RemoteEndPoint =newIPEndPoint(IPAddress.Parse("127.0.0.1"), 8596);
17            ConnectSAE.Completed +=newEventHandler<SOCKETASYNCEVENTARGS>(ConnectSAE_Completed);
18            clientSk.ConnectAsync(ConnectSAE);
19            Console.ReadLine();
20        }
21  
22        staticvoidConnectSAE_Completed(objectsender, SocketAsyncEventArgs e)
23        {
24            Socket clientSk = senderasSocket;
25            if(e.SocketError == SocketError.Success && clientSk.Connected)
26            {
27                SocketAsyncEventArgs SendSAE =newSocketAsyncEventArgs();
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 +=newEventHandler<SOCKETASYNCEVENTARGS>(SendSAE_Completed);
31  
32                SocketAsyncEventArgs RecieveSAE =newSocketAsyncEventArgs();
33                byte[] buffer =newbyte[2048];//因为我们不知道上面的字符串究竟会场生多少字节,这里我们就设置一个理论上可以满足大小的值2046。
34                RecieveSAE.SetBuffer(buffer, 0, buffer.Length);
35                RecieveSAE.Completed +=newEventHandler<SOCKETASYNCEVENTARGS>(RecieveSAE_Completed);
36  
37                //先调用异步接收,再调用异步发送。让你体验到异步明显非一般的感觉。
38                clientSk.ReceiveAsync(RecieveSAE);
39                clientSk.SendAsync(SendSAE);
40            }
41        }
42  
43        staticvoidRecieveSAE_Completed(objectsender, SocketAsyncEventArgs e)
44        {
45            Socket sk = senderasSocket;
46            byte[] data = e.Buffer; //注意这里,如何取关联到套接字的发送接受的缓冲区中的值。
47            stringmsg = System.Text.Encoding.UTF8.GetString(data);
48            Console.WriteLine("Message received: "+msg);
49  
50            //sk.DisconnectAsync();//你看看 该怎么做呢?
51        }
52  
53        staticvoidSendSAE_Completed(objectsender, SocketAsyncEventArgs e)
54        {
55            Socket sk = senderasSocket;
56            if(e.SocketError == SocketError.Success)
57            {
58                Console.WriteLine("Send complete!");
59            }
60        }
61  
62          
63    }
64}</SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS>
 
1<SOCKETASYNCEVENTARGS><SOCKETASYNCEVENTARGS><SOCKETASYNCEVENTARGS><IMG src="http://pic002.cnblogs.com/images/2011/79702/2011070520394016.jpg"><BR></SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS></SOCKETASYNCEVENTARGS>

然后是BenginXXXX 和 EndXXXX的

Server

001usingSystem;
002usingSystem.Collections.Generic;
003usingSystem.Text;
004usingSystem.Net.Sockets;
005usingSystem.Net;
006  
007namespaceSocketTestt
008{
009    publicclassMyObject
010    {
011        #region 类字段
012  
013        privateSocket _Socket;
014        privatestring_MyName = "";
015        privatebyte[] _Buffer;
016  
017  
018        #endregion
019  
020        #region 类属性
021  
022        publicSocket Socket
023        {
024            get{ return_Socket; }
025            set{ _Socket = value; }
026        }
027  
028  
029        publicbyte[] Buffer
030        {
031            get{ return_Buffer; }
032            set{ _Buffer = value; }
033        }
034  
035  
036        publicstringMyName
037        {
038            get{ return_MyName; }
039            set{ _MyName = value; }
040        }
041  
042        #endregion
043  
044        #region 构造函数
045  
046        publicMyObject(Socket socket, stringmyName)
047        {
048            _Socket = socket;
049            _MyName = myName;
050        }
051        publicMyObject(Socket socket, stringmyName,byte[] buffer)
052        {
053            _Socket = socket;
054            _MyName = myName;
055            _Buffer = buffer;
056        }
057  
058        #endregion
059    }
060  
061    classProgram
062    {
063        staticvoidMain(string[] args)
064        {
065            Socket server =newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
066  
067            server.Bind(newIPEndPoint(IPAddress.Parse("127.0.0.1"), 8596));
068            server.Listen(1);
069  
070            server.BeginAccept(newAsyncCallback(AcceptComplete),newMyObject(server,"开始连接了"));
071  
072            Console.ReadLine();
073  
074        }
075  
076  
077        staticvoidAcceptComplete(IAsyncResult ar)
078        {
079            MyObject myObj = ar.AsyncStateasMyObject;
080            Socket serverSk = myObj.Socket.EndAccept(ar);
081  
082            byte[] buffer =newbyte[2048];//虽然不知道会收到多少,但是多了总比少了好。
083  
084            serverSk.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,newAsyncCallback(RecievedComplete), newMyObject(serverSk, "开始接收了", buffer));
085  
086            byte[] datas = System.Text.Encoding.UTF8.GetBytes("I know , Just put it!");
087            serverSk.BeginSend(datas, 0, datas.Length, SocketFlags.None,newAsyncCallback(SendComplete), newMyObject(serverSk, "开始发送了", datas));
088  
089        }
090  
091        staticvoidSendComplete(IAsyncResult ar)
092        {
093            MyObject myObj = ar.AsyncStateasMyObject;
094            Socket sk = myObj.Socket;
095              
096            intsended = sk.EndSend(ar);
097  
098            Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer));
099        }
100  
101        staticvoidRecievedComplete(IAsyncResult ar)
102        {
103  
104            MyObject myObj = ar.AsyncStateasMyObject;
105            Socket sk = myObj.Socket;
106  
107            intrecieved = sk.EndReceive(ar);
108  
109            Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer));
110        }
111    }
112}
Client
001usingSystem;
002usingSystem.Collections.Generic;
003usingSystem.Text;
004usingSystem.Net.Sockets;
005usingSystem.Net;
006  
007namespaceSocketTwo
008{
009    publicclassMyObject
010    {
011        #region 类字段
012  
013        privateSocket _Socket;
014        privatestring_MyName = "";
015        privatebyte[] _Buffer;
016  
017  
018        #endregion
019  
020        #region 类属性
021  
022        publicSocket Socket
023        {
024            get{ return_Socket; }
025            set{ _Socket = value; }
026        }
027  
028  
029        publicbyte[] Buffer
030        {
031            get{ return_Buffer; }
032            set{ _Buffer = value; }
033        }
034  
035  
036        publicstringMyName
037        {
038            get{ return_MyName; }
039            set{ _MyName = value; }
040        }
041  
042        #endregion
043  
044        #region 构造函数
045  
046        publicMyObject(Socket socket, stringmyName)
047        {
048            _Socket = socket;
049            _MyName = myName;
050        }
051        publicMyObject(Socket socket, stringmyName, byte[] buffer)
052        {
053            _Socket = socket;
054            _MyName = myName;
055            _Buffer = buffer;
056        }
057  
058        #endregion
059    }
060  
061    classProgram
062    {
063        staticvoidMain(string[] args)
064        {
065            Socket clientSk =newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
066  
067            clientSk.BeginConnect(newIPEndPoint(IPAddress.Parse("127.0.0.1"), 8596),newAsyncCallback(ConnectComplete), newMyObject(clientSk, "开始连接了"));
068  
069            Console.ReadLine();
070        }
071  
072  
073        staticvoidConnectComplete(IAsyncResult ar)
074        {
075            MyObject myObj = ar.AsyncStateasMyObject;
076            Socket clientSk = myObj.Socket;
077  
078            byte[] datas = System.Text.Encoding.UTF8.GetBytes("I always want put things together!");
079            clientSk.BeginSend(datas, 0, datas.Length, SocketFlags.None,newAsyncCallback(SendComplete), newMyObject(clientSk, "开始发送了", datas));
080  
081  
082            byte[] buffer =newbyte[2048];//虽然不知道会收到多少,但是多了总比少了好。
083  
084            clientSk.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,newAsyncCallback(RecievedComplete), newMyObject(clientSk, "开始接收了", buffer));
085  
086        }
087  
088        staticvoidSendComplete(IAsyncResult ar)
089        {
090            MyObject myObj = ar.AsyncStateasMyObject;
091            Socket sk = myObj.Socket;
092  
093            intsended = sk.EndSend(ar);
094  
095            Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer));
096        }
097  
098        staticvoidRecievedComplete(IAsyncResult ar)
099        {
100  
101            MyObject myObj = ar.AsyncStateasMyObject;
102            Socket sk = myObj.Socket;
103  
104            intrecieved = sk.EndReceive(ar);
105  
106            Console.WriteLine(System.Text.Encoding.UTF8.GetString(myObj.Buffer));
107        }
108    }
109}

 The end.

附:

启动第一个项目

启动第二个...第N个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值