在C#Winform中使用Socket.BeginConnect()连接服务器,并且IAsyncResult对象未返回错
本文关键字:并且 服务器 IAsyncResult 对象 返回 连接 C#Winform Socket BeginConnect | 更新日期: 2023-09-27 18:28:23
我正在做一个应用程序,它要求我作为客户端连接到服务器并从服务器接收数据。当连接断开时,我需要重新连接。以下是我的代码:
public enum MySocketState
{
Disconnected = 0,
Connecting,
Connected
}
public Socket theDevSock = null;
public MySocketState sockState = MySocketState.Disconnected;
void DataProcess()
{
try
{
if (theDevSock == null || sockState == MySocketState.Disconnected)
{
Console.WriteLine("Trying to connect...");
StartConnect();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public bool StartConnect(/*AsyncCallback requestCallback*/)
{
Socket theSocket = null;
try
{
Console.WriteLine("Start connect to server...");
theSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
theSocket.BeginConnect("192.168.1.10", 1000, ConnectCallback, theSocket);
sockState = MySocketState.Connecting;
return true;
}
catch (Exception ex)
{
Console.WriteLine("#### Unable to connect to server...");
}
CloseSocket();
return false;
}
void ConnectCallback(IAsyncResult ar)
{
try
{
theDevSock = (Socket)ar.AsyncState;
if (theDevSock != null)
{
if (theDevSock.Connected)
{
sockState = MySocketState.Connected;
Console.WriteLine("Server is connected...");
theDevSock.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, this.ReceiveCallback, theDevSock);
return;
}
}
Console.WriteLine("Failed to connect to server...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
CloseSocket();
}
private void ReceiveCallback(IAsyncResult AR)
{
try
{
if (theDevSock == null)
theDevSock = (Socket)AR.AsyncState;
int recieved = theDevSock.EndReceive(AR); // Error occur in this line after re-connection.
if (recieved <= 0)
{
CloseSocket();
return;
}
byte[] recData = new byte[recieved];
Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);
string strData = ASCIIEncoding.ASCII.GetString(recData);
Console.WriteLine(strData);
//Process the data stored in recData
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
CloseSocket();
}
finally
{
try
{
//Start receiving again
if (theDevSock != null)
theDevSock.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, ReceiveCallback, theDevSock);
}
catch (Exception ex2)
{ }
}
}
public void CloseSocket()
{
try
{
if (theDevSock != null)
{
if (theDevSock.Connected)
theDevSock.Shutdown(SocketShutdown.Both);
theDevSock.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
theDevSock = null;
sockState = MySocketState.Disconnected;
}
private void timer1_Tick(object sender, EventArgs e)
{
DataProcess();
}
}
我使用计时器(timer1_tick)来检测服务器是否已连接。
如果连接已断开,则编码在重新连接回服务器时没有问题。问题是在重新连接之后,当它从服务器接收到第一个数据时,线路int recieved = theDevSock.EndReceive(AR)
出现错误。错误消息如下:
A first chance exception of type 'System.ArgumentException' occurred in System.dll
A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
System.ArgumentException: The IAsyncResult object was not returned from the corresponding asynchronous method on this class.
Parameter name: asyncResult
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult, SocketError& errorCode)
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at fform.ReceiveCallback(IAsyncResult AR) in c:'Work'Project 2015'Form1.cs:line 163
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult, SocketError& errorCode)
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at fform.Form1.ReceiveCallback(IAsyncResult AR) in c:'Work'Project 2015'Form1.cs:line 163
为什么没有返回IAsyncResult对象?
根据MSDN
异步BeginConnect操作必须通过调用EndConnect方法。通常,该方法由requestCallback委托。
在中
void ConnectCallback(IAsyncResult ar)
在开始接收之前,您应该为EndConnect
设置一行
void ConnectCallback(IAsyncResult ar)
{
try
{
theDevSock = (Socket)ar.AsyncState;
theDevSock.EndConnect(ar);
//blabla
}
}
否则,连接并接收数据的套接字可能是不同的
注意:我不希望将调用BeginConnect
的Socket theSocket
放在类范围内,而不是方法范围内,然后将其传递给theDevSock
,因为它们最终是同一个套接字。