SOCKET异步通信中为什么要使用c 异步回调函数数

C# Socket异步通信 - kingmoon - 博客园
随笔 - 49, 文章 - 0, 评论 - 134, 引用 - 0
C# Socket异步通信&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
TCPServer&
1、使用的通讯通道:socket
2、用到的基本功能:
BeginAccept
BeginReceive&
EndReceive
3、函数参数说明
&Socket listener = new Socket(AddressFamily.InterNetwork,
&&&&&&&&&&& SocketType.Stream, ProtocolType.Tcp);
&新建socket所使用的参数均为系统预定义的量,直接选取使用。
listener.Bind(localEndPoint);
localEndPoint 表示一个定义完整的终端,包括IP和端口信息。
//new IPEndPoint(IPAddress,port)
//IPAdress.Parse("192.168.1.3")
listener.Listen(100);
&&& listener.BeginAccept(
&&&&&&&&&&&&&&&&&&& new AsyncCallback(AcceptCallback),
&&&&&&&&&&&&&&&&&&& listener);
& AsyncCallback(AcceptCallback),一旦连接上后的回调函数为AcceptCallback。当系统调用这个函数时,自动赋予的输入参数为IAsyncResoult类型变量ar。
&& listener,连接行为的容器。
Socket handler = listener.EndAccept(ar);
完成连接,返回此时的socket通道。
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
&&&&&&&&&&& new AsyncCallback(ReadCallback), state);
接收的字节,0,字节长度,0,接收时调用的回调函数,接收行为的容器。
容器的结构类型为:
public class StateObject{
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();}
容器至少为一个socket类型。
===============
& // Read data from the client socket.
&&&&&&& int bytesRead = handler.EndReceive(ar);
完成一次连接。数据存储在state.buffer里,bytesRead为读取的长度。
handler.BeginSend(byteData, 0, byteData.Length, 0,
&&&&&&&&&&& new AsyncCallback(SendCallback), handler);
发送数据byteData,回调函数SendCallback。容器handler
int bytesSent = handler.EndSend(ar);
发送完毕,bytesSent发送字节数。
4 程序结构
byte[] bytes = new Byte[1024];
IPAddress ipAddress = IPAddress.Parse("192.168.1.104");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// 生成一个TCP的socket
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
// Set the event to nonsignaled state.
allDone.Reset();
//开启异步监听socket
Console.WriteLine("Waiting for a connection");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// 让程序等待,直到连接任务完成。在AcceptCallback里的适当位置放置allDone.Set()语句.
allDone.WaitOne();
Console.WriteLine("\nPress ENTER to continue");
Console.Read();
&连接行为回调函数AcceptCallback:
&&& public static void AcceptCallback(IAsyncResult ar)
&&&&&&& //添加此命令,让主线程继续.
&&&&&&& allDone.Set();
&&&&&&& // 获取客户请求的socket
&&&&&&& Socket listener = (Socket)ar.AsyncS
&&&&&&& Socket handler = listener.EndAccept(ar);
&&&&&&& // 造一个容器,并用于接收命令.
&&&&&&& StateObject state = new StateObject();
&&&&&&& state.workSocket =
&&&&&&& handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
&&&&&&&&&&& new AsyncCallback(ReadCallback), state);
读取行为的回调函数ReadCallback:
&&& public static void ReadCallback(IAsyncResult ar)
&&&&&&& String content = String.E
&&&&&&& // 从异步state对象中获取state和socket对象.
&&&&&&& StateObject state = (StateObject)ar.AsyncS
&&&&&&& Socket handler = state.workS
&&&&&&& // 从客户socket读取数据.
&&&&&&& int bytesRead = handler.EndReceive(ar);
&&&&&&& if (bytesRead & 0)
&&&&&&&&&&& // 如果接收到数据,则存起来
&&&&&&&&&&& state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
&&&&&&&&&&& // 检查是否有结束标记,如果没有则继续读取
&&&&&&&&&&& content = state.sb.ToString();
&&&&&&&&&&& if (content.IndexOf("&EOF&") & -1)
&&&&&&&&&&& {
&&&&&&&&&&&&&&& //所有数据读取完毕.
&&&&&&&&&&&&&&& Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
&&&&&&&&&&&&&&&&&&& content.Length, content);
&&&&&&&&&&&&&&& // 给客户端响应.
&&&&&&&&&&&&&&& Send(handler, content);
&&&&&&&&&&& }
&&&&&&&&&&& else
&&&&&&&&&&& {
&&&&&&&&&&&&&&& // 接收未完成,继续接收.
&&&&&&&&&&&&&&& handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
&&&&&&&&&&&&&&& new AsyncCallback(ReadCallback), state);
&&&&&&&&&&& }
发送消息给客户端:
private static void Send(Socket handler, String data)
&&&&&&& // 消息格式转换.
&&&&&&& byte[] byteData = Encoding.ASCII.GetBytes(data);
&&&&&&& // 开始发送数据给远程目标.
&&&&&&& handler.BeginSend(byteData, 0, byteData.Length, 0,
&&&&&&&&&&& new AsyncCallback(SendCallback), handler);
private static void SendCallback(IAsyncResult ar)
&&&&&&&&&&& // 从state对象获取socket.
&&&&&&&&&&& Socket handler = (Socket)ar.AsyncS
&& &&&&&&&&&//完成数据发送
&&&&&&&&&&& int bytesSent = handler.EndSend(ar);
&&&&&&&&&&& Console.WriteLine("Sent {0} bytes to client.", bytesSent);
&&&&&&&&&&& handler.Shutdown(SocketShutdown.Both);
&&&&&&&&&&& handler.Close();
在各种行为的回调函数中,所对应的socket都从输入参数的AsyncState属性获得。使用(Socket)或者(StateObject)进行强制转换。BeginReceive函数使用的容器为state,因为它需要存放传送的数据。
而其余接收或发送函数的容器为socket也可。
2 &using System.N
3 &using System.Net.S
4 using System.T
5 using System.T
7 // State object for reading client data asynchronously
8 public class StateObject
socket. 11
public Socket workSocket = null; 12
// Size of receive buffer. 13
public const int BufferSize = 1024; 14
// Receive buffer. 15
public byte[] buffer = new byte[BufferSize]; 16
// Received data string. 17
public StringBuilder sb = new StringBuilder(); 18 } 19
20 public class AsynchronousSocketListener 21 { 22
// Thread signal. 23
public static ManualResetEvent allDone = new ManualResetEvent(false); 24
public AsynchronousSocketListener() 26
public static void StartListening() 30
// Data buffer for incoming data. 32
byte[] bytes = new Byte[1024]; 33
// Establish the local endpoint for the socket. 35
// The DNS name of the computer 36
// running the listener is "". 37
//IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); 38
IPAddress ipAddress = IPAddress.Parse("192.168.1.104"); 39
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); 41
// Create a TCP/IP socket. 43
Socket listener = new Socket(AddressFamily.InterNetwork, 44
SocketType.Stream, ProtocolType.Tcp); 45
// Bind the socket to the local endpoint and listen for incoming connections. 47
listener.Bind(localEndPoint); 50
listener.Listen(100); 51
while (true) 52
// Set the event to nonsignaled state. 54
allDone.Reset(); 55
// Start an asynchronous socket to listen for connections. 57
Console.WriteLine("Waiting for a connection"); 58
listener.BeginAccept( 59
new AsyncCallback(AcceptCallback), 60
listener); 61
// Wait until a connection is made before continuing. 63
allDone.WaitOne(); 64
catch (Exception e) 67
Console.WriteLine(e.ToString()); 69
Console.WriteLine("\nPress ENTER to continue"); 72
Console.Read(); 73
public static void AcceptCallback(IAsyncResult ar) 76
// Signal the main thread to continue. 78
allDone.Set(); 79
// Get the socket that handles the client request. 81
Socket listener = (Socket)ar.AsyncS 82
Socket handler = listener.EndAccept(ar); 83
// Create the state object. 85
StateObject state = new StateObject(); 86
state.workSocket = 87
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 88
public static void ReadCallback(IAsyncResult ar) 91
String content = String.E 93
// Retrieve the state object and the handler socket 95
// from the asynchronous state object. 96
StateObject state = (StateObject)ar.AsyncS 97
Socket handler = state.workS 98
// Read data from the client socket. 100
int bytesRead = handler.EndReceive(ar);101 102
if (bytesRead & 0)103
might be more data, so store the data received so far.105
state.sb.Append(Encoding.ASCII.GetString(106
state.buffer, 0, bytesRead));107 108
// Check for end-of-file tag. If it is not there, read 109
// more data.110
content = state.sb.ToString();111
if (content.IndexOf("&EOF&") & -1)112
// All the data has been read from the 114
// client. Display it on the console.115
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",content.Length, content);116 117
// Echo the data back to the client.118
Send(handler, content);119
// Not all data received. Get more.123
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);124
private static void Send(Socket handler, String data)129
// Convert the string data to byte data using ASCII encoding.131
byte[] byteData = Encoding.ASCII.GetBytes(data);132 133
// Begin sending the data to the remote device.134
handler.BeginSend(byteData, 0, byteData.Length, 0,135
new AsyncCallback(SendCallback), handler);136
private static void SendCallback(IAsyncResult ar)141 142
// Retrieve the socket from the state object.146
Socket handler = (Socket)ar.AsyncS147 148
// Complete sending the data to the remote device.149
int bytesSent = handler.EndSend(ar);150
Console.WriteLine("Sent {0} bytes to client.", bytesSent);151
handler.Shutdown(SocketShutdown.Both);152
handler.Close();153
catch (Exception e)156 157
Console.WriteLine(e.ToString());159
public static int Main(String[] args)163 164
StartListening();166
return 0;167
}168 169 }Which part of syntax provides the information that this function should run in other thread and be non-blocking?
Let's consider simple asynchronous I/O in node.js
var fs = require('fs');
var path = process.argv[2];
fs.readFile(path, 'utf8', function(err,data) {
var lines = data.split('\n');
console.log(lines.length-1);
What exactly makes the trick that it happens in background? Could anyone explain it precisely or paste a link to some good resource? Everywhere I looked there is plenty of info about what callback is, but nobody explains why it actually works like that.
This is not the specific question about node.js, it's about general concept of callback in each programming language.
Probably the example I provided is not best here. So let's do not consider this node.js code snippet. I'm asking generally - what makes the trick that program keeps executing when encounter callback function. What is in syntax
that makes callback concept a non-blocking one?
Thanks in advance!
解决方案 There is nothing in the syntax that tells you your callback is executed asynchronously. Callbacks can be asynchronous, such as:
setTimeout(function(){
console.log("this is async");
or it can be synchronous, such as:
an_array.forEach(function(x){
console.log("this is sync");
So, how can you know if a function will invoke the callback synchronously or asynchronously? The only reliable way is to read the documentation.
You can also write a test to find out if documentation is not available:
var t = "this is async";
some_function(function(){
t = "this is sync";
console.log(t);
How asynchronous code work
Javascript, per se, doesn't have any feature to make functions asynchronous. If you want to write an asynchronous function you have two options:
Use another asynchronous function such as setTimeout or web workers to execute your logic.
Write it in C.
As for how the C coded functions (such as setTimeout) implement asynchronous execution? It all has to do with the event loop (or mostly).
The Event Loop
Inside the web browser there is this piece of code that is used for networking. Originally, the networking code could only download one thing: the HTML page itself. When Mosiac invented the &img& tag the networking code evolved to download multiple resources. Then Netscape implemented
of images, they had to make the networking code asynchronous so that they can draw the page before all images are loaded and update each image progressively and individually. This is the origin of the event loop.
In the heart of the browser there is an event loop that evolved from asynchronous networking code. So it's not surprising that it uses an I/O primitive as its core:
(or something similar such as poll, epoll etc. depending on OS).
The select() function in C allows you to wait for multiple I/O operations in a single thread without needing to spawn additional threads. select() looks something like:
select (max, readlist, writelist, errlist, timeout)
To have it wait for an I/O (from a socket or disk) you'd add the file descriptor to the readlist and it will return when there is data available on any of your I/O channels. Once it returns you can continue processing the data.
The javascript interpreter saves your callback and then calls the select() function. When select() returns the interpreter figures out which callback is associated with which I/O channel and then calls it.
Conveniently, select() also allows you to specify a timeout value. By carefully managing the timeout passed to select() you can cause callbacks to be called at some time in the future. This is how setTimeout and setInterval are implemented. The interpreter keeps a list of all timeouts and calculates what it needs to pass as timeout to select(). Then when select() returns in addition to finding out if there are any callbacks that needs to be called due to an I/O operation the interpreter also checks for any expired timeouts that needs to be called.
So select() alone covers almost all the functionality necessary to implement asynchronous functions. But modern browsers also have web workers. In the case of web workers the browser spawns threads to execute javascript code asynchronously. To communicate back to the main thread the workers must still interact with the event loop (the select() function).
Node.js also spawns threads when dealing with file/disk I/O. When the I/O operation completes it communicates back with the main event loop to cause the appropriate callbacks to execute.
Hopefully this answers your question. I've always wanted to write this answer but was to busy to do so previously. If you want to know more about non-blocking I/O programming in C I suggest you take a read this:
本文地址: &
语法的哪一部分提供了这个函数应该在其他线程中运行并且是非阻塞的信息?
让我们考虑node.js中的简单异步I / O
var fs = require('fs');
var path = process.argv [2];
fs.readFile(path,'utf8',function(err,data){ var lines = data.split('\\\');
console.log (lines.length-1); });
究竟是什么让它在背景中发生的伎俩?任何人可以准确地解释它或粘贴一些链接到一些好的资源?每一个地方,我看到有很多信息,回调是什么,但没有人解释为什么它实际上这样工作。
这不是关于node.js的具体问题,关于每种编程语言中回调的一般概念。
可能我提供的示例不是最好的这里。所以让我们不要考虑这个node.js代码片段。我一般问 - 什么使程序在遇到回调函数时保持执行的伎俩。什么是语法,使回调概念是一个非阻塞的?
提前感谢!
解决方案 在语法中有无异常,告诉您回调异步执行。回调可以是异步的,例如:
setTimeout(function(){ console.log “); },100);
或它可以是同步的,例如:
an_array.forEach(function(x){ console.log(“this is sync”); });
那么,如何知道函数是否会同步或异步调用回调?唯一可靠的方法是阅读文档。
您还可以编写一个测试,以确定文档是否不可用:
var t =“this is async”;
some_function(function(){ t =“this is sync”; });
console.log(t);
异步代码如何工作
Javascript本身没有任何功能使异步函数。如果你想写异步函数,你有两个选择:
使用另一个异步函数,例如
对于C代码函数(如 setTimeout )如何实现异步执行?
浏览器有一块用于网络的代码。最初,网络代码只能下载一件事:HTML页面本身。当Mosiac发明了& img& 标记时,网络代码演变为下载多个资源。然后Netscape实现了图像的,他们必须使网络代码异步,以便他们可以绘制在所有图像被加载并逐渐地和逐个地更新每个图像之前。这是事件循环的起源。
浏览器的核心是从异步网络代码演化而来的事件循环。因此,使用I / O原语作为其核心并不奇怪:(或类似于poll,epoll等,取决于操作系统)。
在C中的 select()函数允许您在单个线程中等待多个I / O操作,而无需生成额外的线程。
select()看起来像:
select(max,readlist, writelist,errlist,timeout)
让它等待一个I / ),您可以将文件描述符添加到 readlist ,并且当任何I / O通道上有可用数据时,它将返回。一旦返回,您可以继续处理数据。
javascript解释器保存您的回调,然后调用 select()功能。当 select()返回解释器确定哪个回调与哪个I / O通道相关联,然后调用它。
方便地, select()也允许您指定 timeout 值。通过仔细管理传递给 select()的 timeout ,可以使回调在将来某个时候被调用。这是如何实现 setTimeout 和 setInterval 。解释器保存所有超时的列表,并计算需要将 timeout 传递给 select()的内容。然后,当 select()返回时,除了查找是否有任何回调需要由于I / O操作而被调用,解释器还会检查任何过期的超时
因此, select()几乎覆盖了实现异步函数所需的所有功能。但现代浏览器也有网络工作者。在Web工作者的情况下,浏览器生成线程以异步地执行JavaScript代码。要回到主线程,工作者必须仍然与事件循环( select()函数)交互。
Node.js还在处理文件/磁盘I / O时生成线程。当I / O操作完成时,它与主事件循环进行通信,以便执行适当的回调。
希望这回答了你的问题。我一直想写这个答案,但以前忙于这样做。如果你想了解更多关于非阻塞I / O编程在CI建议你读一读这:
本文地址: &
扫一扫关注官方微信[转载]Socket同步异步通信汇总(C#)
本人比较水,以前没碰过socket编程,本着一股小强精神花了两天硬吃了基于C#的同步异步收发,顺便熟悉了下C#的线程编程,代码参考了不少网上已有的版本,如有雷同,本人绝无抄袭之意,只是希望站在巨人的肩上能够看得更远。
那么进入本文的正题。Socket编程时网络编程的基础,C#的NET库封装了网络通信的诸多API,简要介绍几个常用的函数:&
&1.Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
网络套接字的类。其中第一个参数表示支持的ip协议类型,这里选择支持ipv4,也可选择支持ipV6,第二个参数表示是基于数据流的,第三个参数是socket绑定的协议类型。具体的参见msdn,不详细叙述了。
& & 2.IPEndPoint(ip,
port);我理解我建立一个IP终端,ip为ip地址,port为监听的端口。
3.socket.Bind(Ipendpoint);将终端和套接字绑定
4.socket.Listen(500);socket的监听函数,参数为最多挂起数目。()
5.Connected:网络的连接情况&
6.socket.Accept();获取远程请求的socket套接字
7.temp_socket.Receive(recvBytes, recvBytes.Length,
0);接收函数,recvBytes为接收缓冲区,第二个参数为数据长度,第三个参数为缓冲区起始位置。
8.temp_socket.Send(Byte[]); //发送数据 &
9.&temp_socket.Close();//关闭socket连接
&以上是同步socket的一些基本的函数,两天时间本人也还没来得及细细研究每个函数的具体意义和各种重载,粗略记录其基本的作用。对应于异步的socket收发,由于线程不再没有数据的时候阻塞,因此采用回调函数的形式操作socket的连接,数据的接受和发送。其中涉及线程的阻塞与唤醒,在接下来的代码中大家可以研究下期间的细节。异步的socket通信包含了几组常用的函数如下:
& &1.(连接)
& &tcpsend.BeginConnect(end,
new AsyncCallback(ConnectedCallback), tcpsend); //调用回调函数(1)
&&client.EndConnect(ar);(2)
&其中(1)操作将线程挂起,调用回调函数执行余下的操作,(2)在回调函数中执行,这才算真正的连接完毕,然后唤醒线程执行余下的操作。
& 2.(发送)
&&tcpsend.BeginSend(Bysend, 0,
Bysend.Length, 0, new AsyncCallback(SendCallback), tcpsend);
//异步发送数据
&&int bytesSend =
client.EndSend(ar); &//完成发送
&3.(接收)
&&&tcpsend.BeginReceive(receive_buff,
0, receive_buff.Length, 0, new AsyncCallback(ReceiveCallback),
bytesread = client.EndReceive(ar);
&以上三组完成了socket的连接,读写数据的异步操作,异步的优点是不会因为socket端口被单一的线程堵塞时造成其他连接的丢失,多个线程能够保持独立不受影响。
& 下面 给出源代码:
& &Socket同步通信
&(Server)
using System.Collections.G
using <ponentM
using System.D
using System.D
using System.L
using System.T
using System.Windows.F
using System.N
using System.Net.S
using System.T
using System.C
namespace SocketReceive
&&&&public
partial class Form1 :
&&&&&&&&public
int port = 8000;
&&&&&&&&public
&&&&&&&&public
IPEndPoint
&&&&&&&&public
bool listen_flag = false;
&&&&&&&&public
&&&&&&&&public
string server_ip = "192.168.1.110";
&&&&&&&&public
&&&&&&&&Thread[]
SocketThreadList=new
Thread[100];
&&&&&&&&public
&&&&&&&&&&&&InitializeComponent();
&&&&&&&&private
void button1_Click(object sender,
EventArgs e)
&&&&&&&&&&&&IPAddress
ip = IPAddress.Parse(server_ip);
&&&&&&&&&&&&//用指定ip和端口号初始化
&&&&&&&&&&&&tcplisener
= new IPEndPoint(ip, port);
&&&&&&&&&&&&//创建一个socket对象
&&&&&&&&&&&&read
= new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&read.Bind(tcplisener);
&&&&&&&&&&&&&&&&///收到客户端的连接,建立新的socket并接受信息
&&&&&&&&&&&&&&&&read.Listen(500);
//开始监听
&&&&&&&&&&&&&&&&textBox1.Text
= " 等待客户端连接";
&&&&&&&&&&&&&&&&accept
= new Thread(new ThreadStart(Listen));
&&&&&&&&&&&&&&&&accept.Start();
&&&&&&&&&&&&}
&&&&&&&&&&&&catch
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&MessageBox.Show("Error");
&&&&&&&&&&&&}
&&&&&&&&&&&&GC.Collect();
&&&&&&&&&&&&GC.WaitForPendingFinalizers();
&&&&&&&&public
void Listen()
&&&&&&&&&&&&Thread.CurrentThread.IsBackground
= true; //后台线程
&&&&&&&&&&&&while
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Socket
temp_socket = read.Accept();
&&&&&&&&&&&&&&&&textBox1.Text
= "建立连接";
&&&&&&&&&&&&&&&&IPEndPoint
remoteaddr =
(IPEndPoint)temp_socket.RemoteEndP//获取远程的ip地址
&&&&&&&&&&&&&&&&textBox1.Text
= "接收来自" + remoteaddr + "的连接";
&&&&&&&&&&&&&&&&threadread=new
Thread(new ParameterizedThreadStart(AcceptThread));
&&&&&&&&&&&&&&&&threadread.Start(temp_socket);//将连接传递给子线程
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}
&&&&&&&&///
&/summary&
&&&&&&&&public
void AcceptThread(object socket)&
&&&&&&&&&&&&Socket
temp_socket = (Socket)
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&while(temp_socket.Connected)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if(temp_socket.Connected)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&byte[]
recvBytes = new
byte[1024];
&&&&&&&&&&&&&&&&int
&&&&&&&&&&&&&&&&string
recvstr = "";
&&&&&&&&&&&&&&&&bytes
= temp_socket.Receive(recvBytes, recvBytes.Length,
0);//从客户端接受信息
&&&&&&&&&&&&&&&&recvstr
+= Encoding.ASCII.GetString(recvBytes, 0, bytes);
&&&&&&&&&&&&&&&&richTextBox1.Text
&&&&&&&&&&&&&&&&//&&&&&&&&&
MessageBox.Show(recvstr);
&&&&&&&&&&&&&&&&temp_socket.Send(Encoding.Default.GetBytes("Got!"
+ recvstr)); //回发数据&&&
&&&&&&&&&&&&&&&&temp_socket.Close();
&&&&&&&&&&&&&&&&Thread.Sleep(100);
&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&temp_socket.Close();
&&&&&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&catch
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&MessageBox.Show("侦听失败",
&&&&&&&&&&&&}
  Client端
using System.Collections.G
using <ponentM
using System.D
using System.D
using System.L
using System.T
using System.Windows.F
using System.N
using System.Net.S
namespace SocketTest
&&&&public
partial class Form1 :
&&&&&&&public
SocketClient send = new SocketClient(); //构造socket客户端实例
&&&&&&&&public
&&&&&&&&&&&&InitializeComponent();
&&&&&&&&private
void button1_Click(object sender,
EventArgs e)
&&&&&&&&&&&&if
(send.connect(textBox2.Text) ==
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&textBox1.Text
= "成功连接远程计算机";
&&&&&&&&&&&&}
&&&&&&&&&&&&else
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&textBox1.Text
= "连接失败";
&&&&&&&&&&&&}
&&&&&&&&private
void button2_Click(object sender,
EventArgs e)
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&send.send(richTextBox1.Text);
&&&&&&&&&&&&&&&&textBox1.Text
= "发送成功";
&&&&&&&&&&&&&&&&byte[]
back = new byte[1024];
&&&&&&&&&&&&&&&&int
send.tcpsend.Receive((back));
&&&&&&&&&&&&&&&&richTextBox2.Text
= Encoding.ASCII.GetString(back, 0, count);
&&&&&&&&&&&&&&&&send.tcpsend.Close();
&&&&&&&&&&&&}
&&&&&&&&&&&&catch
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&textBox1.Text
= "发送异常";
&&&&&&&&&&&&}
&&&&&&&&private
void Form1_Leave(object sender,
EventArgs e)
&&&&&&&&&&&&send.tcpsend.Close();
  其中SocketClient为
public class SocketClient
&&&&public&
int port=8000;&&&&&&&&&&&&&&&
//监听端口号
&&&&public&
//对服务器端建立TCP连接
&&&&public&
//发送创建套接字
&&&&public&
bool connect_flag=false;
&&&&public
byte[] receive_buff = new byte[1024];
&&&&public
ManualResetEvent connectDone =
new ManualResetEvent(false);
//连接的信号
&&&&public
ManualResetEvent readDone =
new ManualResetEvent(false);&&&
&&&&public
ManualResetEvent sendDone =
new ManualResetEvent(false);&&&
//发送结束
&&&&&public
bool connect(string address)
&&&&&&&&&try{
&&&&&&&&&&&&&tcpsend
= new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//初始化套接字
&&&&&&&&&&&&&&IPEndPoint
remotepoint = new
IPEndPoint(IPAddress.Parse(address),port);//根据ip地址和端口号创建远程终结点
&&&&&&&&&&&&&&&EndPoint
end = (EndPoint)
&&&&&&&&&&&//&
tcpsend.Connect(end);
&&&&&&&&&&&//&
connect_flag =
&&&&&&&&&&&&&&&tcpsend.BeginConnect(end,
new AsyncCallback(ConnectedCallback), tcpsend);
//调用回调函数
&&&&&&&&&&&&&&&connectDone.WaitOne();
&&&&&&&&&&&&&&&return
&&&&&&&&&}
&&&&&&&&&catch
&&&&&&&&&{
&&&&&&&&&&&&&return
&&&&&&&&&}
&&&&&private
void ConnectedCallback(IAsyncResult ar)
&&&&&&&&Socket
client = (Socket)ar.AsyncS
&&&&&&&&client.EndConnect(ar);//
&&&&&&&&connect_flag
&&&&&&&&connectDone.Set();
&&&&&public
void send(string data)
&&&&&&&&&int
length = data.L
&&&&&&&&&Byte[]
Bysend = new
byte[length];
&&&&&&&&&Bysend
= System.Text.Encoding.Default.GetBytes(data); //将字符串指定到指定Byte数组
&&&&&&&&&tcpsend.BeginSend(Bysend,
0, Bysend.Length, 0, new
AsyncCallback(SendCallback),
tcpsend); //异步发送数据
&&&&&&&&&//int
tcpsend.Send(Bysend);&&&&&&&&&&&&&&&&&&&&&&&&
//发送数据
&&&&&&&&&&sendDone.WaitOne();
&&&&&private
void SendCallback(IAsyncResult ar) //发送的回调函数
&&&&&&&&&Socket
client = (Socket)ar.AsyncS
&&&&&&&&&int
bytesSend =
client.EndSend(ar);& //完成发送
&&&&&&&&&sendDone.Set();&
&&&&&public
void receive()&&
//接收数据
&&&&&&&&&//byte[]
receive=new byte[1024];
&&&&&&&&&tcpsend.BeginReceive(receive_buff,
0, receive_buff.Length,0, new AsyncCallback(ReceiveCallback),
&&&&&private
void ReceiveCallback(IAsyncResult ar)
&&&&&&&&&Socket
client = (Socket)ar.AsyncS //获取句柄
&&&&&&&&&int
bytesread =
client.EndReceive(ar);
&&&&&&&&&if
(bytesread &
&&&&&&&&&{
&&&&&&&&&&&&&tcpsend.BeginReceive(receive_buff,
0, receive_buff.Length, 0, new AsyncCallback(ReceiveCallback),
&&&&&&&&&}
&&&&&&&&&else
&&&&&&&&&{
&&&&&&&&&&&&&readDone.Set();
&&&&&&&&&}
  以上是Socket同步的通信,读者可以无视控件的操作,在控制台程序中实现便可,不用我这么繁琐。
&下面是异步的通信形式:
& &Server:
using System.Collections.G
using <ponentM
using System.D
using System.D
using System.L
using System.T
using System.Windows.F
using System.N
using System.Net.S
using System.T
using System.C
namespace SocketReceive
&&&&public
partial class Form1 :
&&&&&&&&public
int port = 8000;
&&&&&&&&public
&&&&&&&&public
IPEndPoint
&&&&&&&&public
bool listen_flag = false;
&&&&&&&&public
&&&&&&&&public
string server_ip = "192.168.1.110";
&&&&&&&&public
&&&&&&&&public
ManualResetEvent AcceptDone =
new ManualResetEvent(false);
//连接的信号
&&&&&&&&public
&&&&&&&&&&&&InitializeComponent();
&&&&&&&&private
void button1_Click(object sender,
EventArgs e)
&&&&&&&&&&&&IPAddress
ip = IPAddress.Parse(server_ip);
&&&&&&&&&&&&//用指定ip和端口号初始化
&&&&&&&&&&&&tcplisener
= new IPEndPoint(ip, port);
&&&&&&&&&&&&//创建一个socket对象
&&&&&&&&&&&&read
= new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
&&&&&&&&&&&&read.Bind(tcplisener);
&&&&&&&&&&&&///收到客户端的连接,建立新的socket并接受信息
&&&&&&&&&&&&read.Listen(500);
//开始监听
&&&&&&&&&&&&textBox1.Text
= " 等待客户端连接";
&&&&&&&&&&&&accept
= new Thread(new ThreadStart(Listen));
&&&&&&&&&&&&accept.Start();
&&&&&&&&&&//&
&&&&&&&&&&&&GC.Collect();
&&&&&&&&&&&&GC.WaitForPendingFinalizers();
&&&&&&&&&&&&&&
&&&&&&&&public
void Listen()
&&&&&&&&&&&&//Thread.CurrentThread.IsBackground
= //后台线程
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&while
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&AcceptDone.Reset();
&&&&&&&&&&&&&&&&&&&&//Socket
temp_socket = read.Accept();
&&&&&&&&&&&&&&&&&&&&read.BeginAccept(new
AsyncCallback(AcceptCallback),
read);& //异步调用
&&&&&&&&&&&&&&&&&&&&AcceptDone.WaitOne();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&catch(Exception
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&MessageBox.Show(er.Message);
&&&&&&&&&&&&}
&&&&&&&&public
void AcceptCallback(IAsyncResult ar) //accpet的回调处理函数
&&&&&&&&&&&&AcceptDone.Set();
&&&&&&&&&&&&Socket
temp_socket = (Socket)ar.AsyncS
&&&&&&&&&&&&Socket
client = temp_socket.EndAccept(ar); //获取远程的客户端
&&&&&&&&&&&&textBox1.Text
= "建立连接";
&&&&&&&&&&&&IPEndPoint
remotepoint = (IPEndPoint)client.RemoteEndP//获取远程的端口
&&&&&&&&&&&&string
remoteaddr =
remotepoint.Address.ToString();&&&&&&&
//获取远程端口的ip地址
&&&&&&&&&&&&textBox1.Text
= "接收来自" + remoteaddr + "的连接";
&&&&&&&&&&&&StateObject
state = new StateObject();
&&&&&&&&&&&&state.workSocket
&&&&&&&&&&&&client.BeginReceive(state.buffer,
0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
&&&&&&&&///
&/summary&
&&&&&&&&public&
void ReadCallback(IAsyncResult ar)
&&&&&&&&&&&&String
content = String.E
&&&&&&&&&&&&//
Retrieve the state object and the handler socket
&&&&&&&&&&&&//
from the asynchronous state object.
&&&&&&&&&&&&StateObject
state = (StateObject)ar.AsyncS
&&&&&&&&&&&&Socket
handler = state.workS
&&&&&&&&&&&&//
Read data from the client socket.&
&&&&&&&&&&&&int
bytesRead =
handler.EndReceive(ar);
&&&&&&&&&&&&if
(bytesRead &
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&string
contentstr = "";
//接收到的数据
&&&&&&&&&&&&&&&&contentstr
+= Encoding.ASCII.GetString(state.buffer, 0,
bytesRead);
&&&&&&&&&&&&&&&&richTextBox1.Text
&&&&&&&&&&&&&&&&byte[]
byteData=Encoding.ASCII.GetBytes("Success:"+contentstr);//回发信息
&&&&&&&&&&&&&&&&handler.BeginSend(byteData,
0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
&&&&&&&&&&&&&&&&handler.BeginReceive(state.buffer,
0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
&&&&&&&&&&&&}
&&&&&&&&private&
void Send(Socket handler, String data)
&&&&&&&&&&&&//
Convert the string data to byte data using ASCII
&&&&&&&&&&&&byte[]
byteData = Encoding.ASCII.GetBytes(data);
&&&&&&&&&&&&//
Begin sending the data to the remote device.
&&&&&&&&&&&&handler.BeginSend(byteData,
0, byteData.Length, 0,
&&&&&&&&&&&&&&&&new
AsyncCallback(SendCallback),
&&&&&&&&private&
void SendCallback(IAsyncResult ar)
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//
Retrieve the socket from the state object.
&&&&&&&&&&&//&&&&
Socket handler = (Socket)ar.AsyncS
&&&&&&&&&&&&&&&&//
Complete sending the data to the remote device.
&&&&&&&&&&//&&&&&
int bytesSent = handler.EndSend(ar);
&&&&&&&&&&&&&&&//
Console.WriteLine("Sent {0} bytes to client.",
bytesSent);
&&&&&&&&&&//&&&&&
richTextBox1.Text = "Send" + bytesSent.ToString() + "bytes to
&&&&&&&&&&//&&&&&
handler.Shutdown(SocketShutdown.Both);
&&&&&&&&&&&//&&&&
handler.Close();
&&&&&&&&&&&&}
&&&&&&&&&&&&catch
(Exception e)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&MessageBox.Show(e.ToString());
&&&&&&&&&&&&}
&&&&public
class StateObject
&&&&&&&&//
Client& socket.
&&&&&&&&public
Socket workSocket = null;
&&&&&&&&//
Size of receive buffer.
&&&&&&&&public
const int BufferSize =
&&&&&&&&//
Receive buffer.
&&&&&&&&public
byte[] buffer = new byte[BufferSize];
&&&&&&&&//
Received data string.
&&&&&&&&public
StringBuilder sb = new StringBuilder();
  Client
using Susing System.Collections.Gusing ponentMusing System.Dusing System.Dusing System.Lusing System.Tusing System.Windows.Fusing System.Nusing System.Net.Susing System.T
namespace SocketTest
public partial class Form1 : Form
public int port = <span STYLE="CoLor: #00;
//监听端口号
public TcpC
//对服务器端建立TCP连接
//发送创建套接字
public bool connect_flag = false;
public byte[] receive_buff = new byte[<span STYLE="CoLor: #24];
public ManualResetEvent connectDone = new ManualResetEvent(false); //连接的信号
public ManualResetEvent readDone = new ManualResetEvent(false);
public ManualResetEvent sendDone = new ManualResetEvent(false);
//发送结束
public bool connect(string address)
tcpsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化套接字
IPEndPoint remotepoint = new IPEndPoint(IPAddress.Parse(address), port);//根据ip地址和端口号创建远程终结点
EndPoint end = (EndPoint)
tcpsend.Connect(end);
connect_flag =
tcpsend.BeginConnect(end, new AsyncCallback(ConnectedCallback), tcpsend); //调用回调函数
connectDone.WaitOne();
return true;
return false;
private void ConnectedCallback(IAsyncResult ar)
Socket client = (Socket)ar.AsyncS
client.EndConnect(ar);//
connect_flag = true;
connectDone.Set();
public void send(string data)
int length = data.L
Byte[] Bysend = new byte[length];
Bysend = System.Text.Encoding.Default.GetBytes(data); //将字符串指定到指定Byte数组
tcpsend.BeginSend(Bysend, <span STYLE="CoLor: #, Bysend.Length, <span STYLE="CoLor: #, new AsyncCallback(SendCallback), tcpsend); //异步发送数据
//int i = tcpsend.Send(Bysend);
//发送数据
sendDone.WaitOne();
private void SendCallback(IAsyncResult ar) //发送的回调函数
Socket client = (Socket)ar.AsyncS
int bytesSend = client.EndSend(ar);
//完成发送
sendDone.Set();
public void receive()
//接收数据
//byte[] receive=new byte[1024];
tcpsend.BeginReceive(receive_buff, <span STYLE="CoLor: #, receive_buff.Length, <span STYLE="CoLor: #, new AsyncCallback(ReceiveCallback), tcpsend);
sendDone.WaitOne();
private void ReceiveCallback(IAsyncResult ar)
Socket client = (Socket)ar.AsyncS //获取句柄
int bytesread = client.EndReceive(ar);
if (bytesread & <span STYLE="CoLor: #)
client.BeginReceive(receive_buff, <span STYLE="CoLor: #, receive_buff.Length, <span STYLE="CoLor: #, new AsyncCallback(ReceiveCallback), client);
string content = Encoding.ASCII.GetString(receive_buff, <span STYLE="CoLor: #, receive_buff.Length);
richTextBox2.Text =// receive_buff.ToString();
readDone.Set();
public Form1()
InitializeComponent();
private void button1_Click(object sender, EventArgs e)
connectDone.Reset();
if (connect(textBox2.Text) == true)
connectDone.WaitOne();
textBox1.Text = "成功连接远程计算机";
textBox1.Text = "连接失败";
private void button2_Click(object sender, EventArgs e)
sendDone.Reset();
send(richTextBox1.Text);
sendDone.WaitOne();
textBox1.Text = "发送成功";
readDone.Reset();
receive();
readDone.WaitOne();
// byte[] back = new byte[1024];
// int count = send.tcpsend.Receive((back));
richTextBox2.Text = Encoding.ASCII.GetString(back, 0, count);
send.tcpsend.Close();
textBox1.Text = "发送异常";
private void Form1_Leave(object sender, EventArgs e)
tcpsend.Close();
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 python 异步回调函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信