这是一个使用异步Socket接收数据的工作(无用)示例。 完整的代码可以在MSDN找到。
public class Class1
{
private static void Receive( Socket client )
{
StateObject state = new StateObject();
state.workSocket = client;
//state.buffer is a empty byte array
client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
private static void ReceiveCallback( IAsyncResult ar )
{
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
//state.buffer contains now all the received data.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
}
}
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
在BeginReceive
方法中,由于没有state.buffer
或ref
关键字,因此无法影响out
字段。
但是字节数组实际上已经改变了值。
state.buffer
Methode中的Receive
字段是如何为空,然后在ReceiveCallback
方法中访问时包含所有收到的数据?
答案 0 :(得分:2)
因为没有ref或out关键字
,所以不可能影响state.buffer字段
没有。这不是真的。 state.buffer
指向的实际对象可以通过其他方法更改,但其引用不能更改。
这是一个简单的例子:
static void Main()
{
byte[] arr = new byte[] { 1, 2, 3, 4, 5 };
ChangeTheObject(arr);
foreach(byte b in arr) {
Console.WriteLine(b);
}
}
static void ChangeTheObject(byte[] arr)
{
arr[2] = 7;
}
Main()
将打印
1
2
7
4
5
对象本身可以通过接收它的方法进行更改。
但是,您无法更改引用本身。
static void ChangeTheReference(byte[] arr)
{
arr = new byte[] { 6, 7, 8, 9, 10 };
}
这不会更改Main()
中原始数组的内容,因为您已重新指定对新对象的本地引用。您没有更改原始对象。这就是ref
关键字派上用场的地方。
示例中的方法是更改数组的内容,而不是引用。
答案 1 :(得分:0)
如果您花时间至少阅读您发布的MSDN链接上的评论,您就会明白发生了什么:
开始从远程设备接收数据。
client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
从远程设备读取数据。
int bytesRead = client.EndReceive(ar);
下次,在声明可能与否之前,花更多时间阅读并理解已经解释的内容。