异步Tcp socket遇到无法访问已释放的对象 System.Net.Sockets

frustrate2 2011-08-23 05:14:36
客户端有个启动访问服务端的按钮,点击第一次是没有问题,但是点击第二次就遇到了问题,报
异常:遇到无法访问已释放的对象 System.Net.Sockets。现在怀疑是服务端的异步发送
引起的,handler.Shutdown(SocketShutdown.Both);handler.Close();客户端没有接收到传来的数据,为null,汇报异常,客户端报异常的代码我已经加红,请各位帮我看看咋回事,我不知道咋改了。
服务端:
Thread newThread;
public static ManualResetEvent allDone = new ManualResetEvent(false);

public delegate void SetRichTextBoxReceiveCallback(string str);
public SetRichTextBoxReceiveCallback setRichTextBoxReceiveCallback;
private void SetRichTextBoxReceive(string str)
{
if (rtb_Content.InvokeRequired)
{
setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
rtb_Content.Invoke(setRichTextBoxReceiveCallback, str);
}
else
{
rtb_Content.AppendText(str);
}
}

private void btn_Start_Click(object sender, EventArgs e)
{
setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
ThreadStart ts = new ThreadStart(acceptConnect);
newThread = new Thread(ts);
newThread.Start();
}

private void btn_Click(object sender, EventArgs e)
{
//newThread.Abort();
System.Environment.Exit(0);
}

/// <summary>
/// 开启一个socket监听线程
/// </summary>
private void acceptConnect()
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 绑定端口,并监听发起的连接请求。
try
{
listener.Bind(endPoint);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
SetRichTextBoxReceive("等待客户端连接请求中......\n");
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception ex)
{
SetRichTextBoxReceive(ex.Message.ToString());
}
}

/// <summary>
/// 接收连接请求
/// </summary>
/// <param name="ar"></param>
public void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();

// Get the socket that handles the client request.
// 获取处理客户端请求的套接字
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);

// Create the state object.实例化类StateObject。
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}

/// <summary>
/// 读取连接请求
/// </summary>
/// <param name="ar"></param>
private void ReadCallback(IAsyncResult ar)
{
string content = string.Empty;

// Retrieve the state object and the handler socket from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;

// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
// All the data has been read from the client. Display it on the console.
SetRichTextBoxReceive("Read " + content.Length + " bytes from socket.\nData:" + content + ".\n");
// Echo the data back to the client.
Send(handler, content);
}
else
{
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
}
}

private void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}

public void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
rtb_Content.Invoke(setRichTextBoxReceiveCallback, "Sent " + bytesSent + " bytes to client.\n");
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception ex)
{
throw ex;
}
}
...全文
794 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lanserzhao 2011-08-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 chichenzhe 的回复:]
高人不敢当.你贴我回过.. 你代码太长,还没有缩进格式....
而且我还说错了,开始还以为你是要架server. 后来才知道是client; client 网上代码一抓一大把.. 你搜索下呀.


长连接就是 这个socket通道 建立之后双方都不 close; 你那个应该是长连接.
没有其他特别约定.是相对于 http 这样短连接模式所有有长连接这样一说.
[/Quote]

讲的都对的,我的疑问就是登录不能完全成功,成功率和delphi相比,比较低,很费解
frustrate2 2011-08-23
  • 打赏
  • 举报
回复
int i=0 在那个地方改?
[Quote=引用 3 楼 chichenzhe 的回复:]
我晕.... 你这代码叫人怎么看啊.

这么长.. 还不按代码格式去发


C# code
int i = 10;
[/Quote]
lanserzhao 2011-08-23
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 frustrate2 的回复:]
谢谢各位的热心帮助,刚学socket,看了段时间的书和资料,开始实际编码了遇到不少问题
[/Quote]

不谢,如果我讲的有用记得给我加分,如果还想学习去看我刚发的帖子,对你应该有些帮助

http://topic.csdn.net/u/20110823/15/6e02718d-fedb-475e-b142-132dcb9634e4.html
frustrate2 2011-08-23
  • 打赏
  • 举报
回复
谢谢各位的热心帮助,刚学socket,看了段时间的书和资料,开始实际编码了遇到不少问题
chichenzhe 2011-08-23
  • 打赏
  • 举报
回复
高人不敢当.你贴我回过.. 你代码太长,还没有缩进格式....
而且我还说错了,开始还以为你是要架server. 后来才知道是client; client 网上代码一抓一大把.. 你搜索下呀.


长连接就是 这个socket通道 建立之后双方都不 close; 你那个应该是长连接.
没有其他特别约定.是相对于 http 这样短连接模式所有有长连接这样一说.
lanserzhao 2011-08-23
  • 打赏
  • 举报
回复
private void btn_Start_Click(object sender, EventArgs e)
{
setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
ThreadStart ts = new ThreadStart(acceptConnect);
newThread = new Thread(ts);
newThread.Start();
}



你把这个 TS 定义到全局变量里看看
lanserzhao 2011-08-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 chichenzhe 的回复:]
都不用看你代码
---------------
客户端有个启动访问服务端的按钮,点击第一次是没有问题,但是点击第二次就遇到了问题,报
异常:遇到无法访问已释放的对象 System.Net.Sockets。
---------------

这说明 server端 或者 client 在做了第1次的交互之后 把socket通道关闭了.
所以你第2次应该重新new socket对象,并且……
[/Quote]


高人,还在不?我还有个问题请教,长连接指的什么?
我的貌似属于长连接不?
http://topic.csdn.net/u/20110823/15/6e02718d-fedb-475e-b142-132dcb9634e4.html

chichenzhe 2011-08-23
  • 打赏
  • 举报
回复
都不用看你代码
---------------
客户端有个启动访问服务端的按钮,点击第一次是没有问题,但是点击第二次就遇到了问题,报
异常:遇到无法访问已释放的对象 System.Net.Sockets。
---------------

这说明 server端 或者 client 在做了第1次的交互之后 把socket通道关闭了.
所以你第2次应该重新new socket对象,并且重新连接.

按上面思路改就行了,也很简单.
但如果非要做 '长连接'的话,那就还是学点socket基础吧, 没基础咋弄都白搭.
chichenzhe 2011-08-23
  • 打赏
  • 举报
回复
我晕.... 你这代码叫人怎么看啊.

这么长.. 还不按代码格式去发

int i = 10;
frustrate2 2011-08-23
  • 打赏
  • 举报
回复
请各位大大给小弟改改,呵呵
frustrate2 2011-08-23
  • 打赏
  • 举报
回复
客户端:
Thread newThread;
Socket client;
// The port number for the remote device.
private const int port = 8090;

// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);

public delegate void SetRichTextBoxReceiveCallback(string str);
public SetRichTextBoxReceiveCallback setRichTextBoxReceiveCallback;
private void SetRichTextBoxReceive(string str)
{
if (rtb_Content.InvokeRequired)
{
setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
rtb_Content.Invoke(setRichTextBoxReceiveCallback, str);
}
else
{
rtb_Content.AppendText(str);
}
}

// The response from the remote device.
private static string response = string.Empty;

private void btn_Request_Click(object sender, EventArgs e)
{
// Connect to a remote device.
try
{
if (newThread != null)
{
newThread.Abort();
}
ThreadStart ts = new ThreadStart(acceptConnect);
newThread = new Thread(ts);
newThread.Start();
}
catch (Exception ex)
{
SetRichTextBoxReceive(ex.Message.ToString() + "\n");
}
}

private void acceptConnect()
{
// Establish the remote endpoint for the socket.The name of the remote device is "127.0.0.1".
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090);

// Create a TCP/IP socket.
//if (client == null && client.Connected)
//{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//}

// Connect to the remote endpoint.
client.BeginConnect(endPoint, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();

// Send test data to the remote device.
Send(client, "This is a test<EOF>");
sendDone.WaitOne();

// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();

// Write the response to the console.
SetRichTextBoxReceive("Response received : " + response + ".\n");

// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}

private void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
SetRichTextBoxReceive("Socket connected to " + client.RemoteEndPoint.ToString() + ".\n");
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception ex)
{
SetRichTextBoxReceive(ex.Message.ToString() + "\n");
}
}

private void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception ex)
{
SetRichTextBoxReceive(ex.Message.ToString() + "\n");
}
}

private void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
private void Send(Socket client, string data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
}

private void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
SetRichTextBoxReceive("Sent " + bytesSent + " bytes to server.\n");
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception ex)
{
SetRichTextBoxReceive(ex.Message.ToString() + "\n");
}
} // There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
// Signal that all bytes have been received.
receiveDone.Set();
}
}
}
catch (Exception ex)
{
SetRichTextBoxReceive(ex.Message.ToString() + "\n");
}
}

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧