提前声明,我的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);
搞定。如果有帮到你,请为我点赞。