C#服务端______空引用异常, Socket和SocketAsyncEventArgs之间需要注意的一点小事

提前声明,我的Socket用的是这种构造。

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

众所周知。

Socket有一个异步接受链接方法:Socket.AcceptAsync(SocketAsyncEventArgs)    (此处的Socket.AcceptAsync只是说明此类下有这个方法,并非指它是静态方法,后面都是这样,静态方法会单独注明)

Socket还有一个异步接受数据的方法:Socket.ReceiveAsync(SocketAsyncEventArgs) 

明眼人都看得出,它们都需要一个SocketAsyncEventArgs类型的变量,正常来说,声明个变量并初始化塞给它们就行了,但事实是半行不行的。

对于Socket.AcceptAsync(SocketAsyncEventArgs) 来说,声明个变量并初始化,然后作为参数是没问题的,不会出问题。

但是,对于Socket.ReceiveAsync(SocketAsyncEventArgs) 来说,仅仅是声明个变量并初始化,那是完全不行的,空引用异常会爆死人。

为什么呢,因为前者只是接受链接,不需要接收数据,不需要数据缓冲区,仅仅需要把客户端对应的socket值引到SocketAsyncEventArgs中的成员变量AcceptSocket上就行。所以你直接初始化,然后传参没问题。

但到了接受异步接受数据的方法这里,你是需要接收数据的,不能仅仅是初始化,你还需要手动对SocketAsyncEventArgs中的成员变量Buffer(字节数组)进行初始化,因为它就是用来接收网络数据的缓冲区,而很不幸的是,SocketAsyncEventArgs的构造方法是没有对这个数组进行初始化的。

所以你拿一个仅仅是实例化的SocketAsyncEventArgs对象扔到Socket.ReceiveAsync(SocketAsyncEventArgs)中肯定报空引用异常,你个空数组连内存都没有拿什么接受人家网络上的数据。

废话不说了,解决方案献上:

错误写法:

SocketAsyncEventArgs receiveArgs=new SocketAsyncEventArgs();

clientSocket.ReceiveAsync(receiveArgs);

这种写法必定回报空引用异常。

正确写法:

SocketAsyncEventArgs receiveArgs=new SocketAsyncEventArgs();

 receiveArgs.SetBuffer(new byte[2048], 0,2048);(很简单明了的方法,要是还有不清楚的,去查一下msdn)

clientSocket.ReceiveAsync(receiveArgs);

搞定。如果有帮到你,请为我点赞。

猜你喜欢

转载自blog.csdn.net/qq_37760273/article/details/105551139