代码如下:using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;using BWU.LogisticsDept.Museum.Extension;namespace BWU.LogisticsDept.Museum.AsynchronousTcpSocket
{
public class AsyncTcpClient : AsynchronousTcp, IAsyncTcpClient
{
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false); private IPEndPoint remoteEP; private String response = String.Empty;
private String logFileName; public AsyncTcpClient(String remoteIP, Int32 remotePort,String logFileName)
: base(remoteIP, remotePort)
{
this.logFileName = logFileName; remoteEP = new IPEndPoint(IPAddress.Parse(IP), Port);
} public Boolean Sending(Byte[] sendBuff)
{
try
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallBack), clientSocket);
connectDone.WaitOne(); Send(clientSocket, sendBuff);
sendDone.WaitOne(); Receive(clientSocket);
receiveDone.WaitOne();//程序在这里出现过长时间等待,加上超时设置可以暂时解决 clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
GC.Collect();
return true;
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
return false;
}
} private void ConnectCallBack(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState; clientSocket.EndConnect(ar);
connectDone.Set();
}
catch(Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void Receive(Socket clientSocket)
{
try
{
StateObject state = new StateObject(); state.WorkSocket = clientSocket;
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void RecevieCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket clientSocket = state.WorkSocket; Int32 bytesRead = clientSocket.EndReceive(ar);//这里出现异常:无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。 if (bytesRead > 0)
{
state.StrBuilder.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead));
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
}
else
{
if (state.StrBuilder.Length > 1)
{
response = state.StrBuilder.ToString();
}
} receiveDone.Set();
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void Send(Socket clientSocket, Byte[] sendBuff)
{
clientSocket.BeginSend(sendBuff, 0, sendBuff.Length, 0, new AsyncCallback(SendCallback), clientSocket);//由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
} private void SendCallback(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState; Int32 bytesSent = clientSocket.EndSend(ar);
sendDone.Set();
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
}
}
}
主要出错的地方我写在代码注释上了,求高手帮助寻找问题,修改代码
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;using BWU.LogisticsDept.Museum.Extension;namespace BWU.LogisticsDept.Museum.AsynchronousTcpSocket
{
public class AsyncTcpClient : AsynchronousTcp, IAsyncTcpClient
{
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false); private IPEndPoint remoteEP; private String response = String.Empty;
private String logFileName; public AsyncTcpClient(String remoteIP, Int32 remotePort,String logFileName)
: base(remoteIP, remotePort)
{
this.logFileName = logFileName; remoteEP = new IPEndPoint(IPAddress.Parse(IP), Port);
} public Boolean Sending(Byte[] sendBuff)
{
try
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallBack), clientSocket);
connectDone.WaitOne(); Send(clientSocket, sendBuff);
sendDone.WaitOne(); Receive(clientSocket);
receiveDone.WaitOne();//程序在这里出现过长时间等待,加上超时设置可以暂时解决 clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
GC.Collect();
return true;
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
return false;
}
} private void ConnectCallBack(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState; clientSocket.EndConnect(ar);
connectDone.Set();
}
catch(Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void Receive(Socket clientSocket)
{
try
{
StateObject state = new StateObject(); state.WorkSocket = clientSocket;
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void RecevieCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket clientSocket = state.WorkSocket; Int32 bytesRead = clientSocket.EndReceive(ar);//这里出现异常:无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。 if (bytesRead > 0)
{
state.StrBuilder.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead));
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
}
else
{
if (state.StrBuilder.Length > 1)
{
response = state.StrBuilder.ToString();
}
} receiveDone.Set();
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void Send(Socket clientSocket, Byte[] sendBuff)
{
clientSocket.BeginSend(sendBuff, 0, sendBuff.Length, 0, new AsyncCallback(SendCallback), clientSocket);//由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
} private void SendCallback(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState; Int32 bytesSent = clientSocket.EndSend(ar);
sendDone.Set();
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
}
}
}
主要出错的地方我写在代码注释上了,求高手帮助寻找问题,修改代码
receiveDone.WaitOne();//程序在这里出现过长时间等待,加上超时设置可以暂时解决
首先一点,你要确认服务器端是否能ping通,有否回应(最好用同步的TCP连上测测)。Int32 bytesRead = clientSocket.EndReceive(ar);//这里出现异常:无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。
你前面有超时的设置,这个是否为空对象的判断是必须要加上的了。
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;using BWU.LogisticsDept.Museum.Extension;namespace BWU.LogisticsDept.Museum.AsynchronousTcpSocket
{
public class AsyncTcpClient : AsynchronousTcp, IAsyncTcpClient
{
private ManualResetEvent connectDone = new ManualResetEvent(false);
private ManualResetEvent sendDone = new ManualResetEvent(false);
private ManualResetEvent receiveDone = new ManualResetEvent(false); private IPEndPoint remoteEP; private String response = String.Empty;
private String logFileName; public AsyncTcpClient(String remoteIP, Int32 remotePort, String logFileName)
: base(remoteIP, remotePort)
{
this.logFileName = logFileName; remoteEP = new IPEndPoint(IPAddress.Parse(IP), Port);
} public Boolean StartSending(Byte[] sendBuff)
{
try
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallBack), clientSocket);
connectDone.WaitOne(); Send(clientSocket, sendBuff);
sendDone.WaitOne(); Receive(clientSocket);
receiveDone.WaitOne(); clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
return true;
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
return false;
}
} private void ConnectCallBack(IAsyncResult ar)
{ try
{
Socket clientSocket = (Socket)ar.AsyncState; clientSocket.EndConnect(ar);
connectDone.Set();
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void Receive(Socket clientSocket)
{
try
{
StateObject state = new StateObject(); state.WorkSocket = clientSocket;
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void RecevieCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket clientSocket = state.WorkSocket; Int32 bytesRead = clientSocket.EndReceive(ar);//无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。 if (bytesRead > 0)
{
state.StrBuilder.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead));
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
}
else
{
if (state.StrBuilder.Length > 1)
response = state.StrBuilder.ToString();
receiveDone.Set();
}
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
} private void Send(Socket clientSocket, Byte[] sendBuff)
{
clientSocket.BeginSend(sendBuff, 0, sendBuff.Length, 0, new AsyncCallback(SendCallback), clientSocket);//由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
} private void SendCallback(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState; Int32 bytesSent = clientSocket.EndSend(ar);
sendDone.Set();
}
catch (Exception e)
{
e.SaveErrorLogToFile(logFileName);
}
}
}
}出错的信息写在了相关代码的后面,现在的情况是,第一次发送是毫无问题的,问题出现在第二次发送数据的时候,而且,有时是“无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。”,有时则是“由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。”。
推荐用网上的EMTASS,实现的不错,一般的异常都已经解决了,csdn中就有下载
====================================怎么样在连接释放后退出RecevieCallback呢?
也就是说SendCallback/RecevieCallback未真正释放.不知哪位高手能给我们这些新手指点一二
[email protected]