我有两个C#程序应该通过WebSockets进行通信,服务器工作正常(也使用Alchemy)并且已经有一段时间了(使用javascript客户端)。但是,连接Alchemy WebSocketClient
会导致在客户端抛出NullReferenceException
。
经过一些调试后,我发现由于_context.Connection.Connected
调用,WebSocketClient.cs
的第187行引发了异常。 _context.Connection是与本地_client
相同的实例,并且在那个时间点都不为null。在msdn.microsoft.com上的TcpClient.Connected
页面上没有列出可能的例外情况(告诉我它不应该抛出任何例外)。
继续前进我注意到_client
类变量在WebSocketClient.cs
的第176行从正常查看实例更改为填充异常的实例:
在此行之后,刚刚在第187行添加的Context
的Dispose()方法被称为断开Connection
(与我_client
的实例相同之前在Context.cs
的第131行提到过。
我的问题是:为什么会发生这种情况,如何阻止它发生并成功连接到所需的WebSocketServer?
如果您需要更多信息,请在评论中不要犹豫。
编辑1
仅在服务器实际侦听时发生异常,如果服务器处于非活动状态,则未到达WebSocketClient.cs
的第176行(这是正确的行为,因为在连接到服务器时调用了OnRunClient()
是的。)
编辑2
按要求StackTrace:
System.NullReferenceException was unhandled
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=System
StackTrace:
at System.Net.Sockets.TcpClient.get_Connected()
at Alchemy.WebSocketClient.SetupContext(Context context) in C:\...\Alchemy\WebSocketClient.cs:regel 187
at Alchemy.WebSocketClient.HandleClientThread() in C:\...\Alchemy\WebSocketClient.cs:regel 94
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
答案 0 :(得分:2)
我看到你使用TcpClient。此类使用Socket类进行数据传输(TcpClient具有此类字段)。据我所知,在某些情况下,此字段可以为null。 TcpClient的Property Connected使用内部Socket实例的Connected属性。像这样:
public bool Connected
{
get
{
return _socket.Connected; // Possible NullRef here!!!
}
}
因此,当此字段为null时,您将获得NullReferenceException。据我所知,当连接未成功建立时可能会发生这种情况。
例如,我在您的代码中看到了这一点:
try
{
_client.EndConnect(result);
}
catch (Exception ex)
{
Disconnect();
connectError = true;
}
using (_context = new Context(null, _client))
{
_context = new Context(null, _client);
_context.BufferSize = 512;
// some code
}
如果连接出错,您将获得异常并执行某些操作,但在这种情况下,您的_client将没有初始化Socket字段。在Context构造函数中,您将尝试使用它的字段(在Connected属性中),您将获得NullReferenceException。
我猜你需要在catch块中添加return。
OR
检查TcpClient的基础属性客户端(http://msdn.microsoft.com/ru-ru/library/system.net.sockets.tcpclient.client(v=vs.110).aspx),如下所示:
if (_client.Client != null && _client.Connected)
{
// do what you need
}
希望这会对你有所帮助。