C#socket通讯两个最经典错误解决方案

经典错误之一 无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”

(1) 问题现场

(2) 问题描述

程序中的某个地方调用到了socket.close后,这个socket还被调用,就出爆出上面错误!

(3) 解决方案

使用下面一句: 


if (stsend != null && stsend.Connected)

stsend != null :这一句在socket.close之后,会无效的,因为关闭socket连接时已经将其所有连接的资源都释放了;故要与Connected全用;

stsend.Connected:获取一个值,该值指示 Socket上次操作是Send还是Receive形式连接到远程主机,如果都不是,那就是断开了。

(4) 扩展说明

所有非托管资源程序员必须能控制资源释放,诸如数据库连接,SOCKET连接等在使用后都应当显示关闭,如果是长连接,在程序退出时应当确保所有占用的连接都被关闭。

经典错误之二 "远程主机强迫关闭了一个现有的连接。"

(1) 问题现场

(2) 问题描述

      如下图,对于网络的经典问题,由于是server和client中的任意一方主动断开连接,导致弹出 “远程主机强迫关闭了一个现在连接”的异常。这种情况,会导致程序提示异常,无法继续往下执行。

(3) 解决方案

      可以通过异常处理的方式,通过异常来提示网络不正常,从而跳出该程序分支,不至于因为异常问题程序瘫痪!

      如下图,一Catch到这类System.Net.Sockets.SocketException异常(当然这里把它设为Exceptioin异常,抓取的范围更广),那么就用MessageBox给用户一个提示,然后从该分支退出就行了。

后记

最近一直在做socket方面的研发. 发现上文中这两个错误都是最常见的, 特转载到我的博客里了.

在这里感谢Net-Spider, 对应的文章链接为: https://www.cnblogs.com/MRRAOBX/articles/3601851.html

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个简单的 C# Socket 通讯解决粘包的示例: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; public class SocketServer { private Socket listener; private const int BUFFER_SIZE = 1024; private byte[] buffer = new byte[BUFFER_SIZE]; public void Start() { listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.Bind(new IPEndPoint(IPAddress.Any, 8080)); listener.Listen(10); Console.WriteLine("Server started on port 8080."); while (true) { Socket client = listener.Accept(); Console.WriteLine("Client connected: " + client.RemoteEndPoint.ToString()); // Start receiving data from client client.BeginReceive(buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReceive), client); } } private void OnReceive(IAsyncResult ar) { Socket client = (Socket)ar.AsyncState; int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { // Convert received bytes to string string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead); // Process received data Console.WriteLine("Received data: " + receivedData); // Continue receiving data from client client.BeginReceive(buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReceive), client); } else { // Client has disconnected Console.WriteLine("Client disconnected: " + client.RemoteEndPoint.ToString()); client.Close(); } } } public class SocketClient { private Socket client; private const int BUFFER_SIZE = 1024; private byte[] buffer = new byte[BUFFER_SIZE]; public void Connect() { client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.BeginConnect(new IPEndPoint(IPAddress.Loopback, 8080), new AsyncCallback(OnConnect), null); } private void OnConnect(IAsyncResult ar) { Console.WriteLine("Connected to server."); client.EndConnect(ar); // Start receiving data from server client.BeginReceive(buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReceive), client); } private void OnReceive(IAsyncResult ar) { Socket client = (Socket)ar.AsyncState; int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { // Convert received bytes to string string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead); // Process received data Console.WriteLine("Received data: " + receivedData); // Continue receiving data from server client.BeginReceive(buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReceive), client); } else { // Server has disconnected Console.WriteLine("Server disconnected."); client.Close(); } } public void Send(string data) { byte[] sendData = Encoding.UTF8.GetBytes(data); client.BeginSend(sendData, 0, sendData.Length, 0, new AsyncCallback(OnSend), null); } private void OnSend(IAsyncResult ar) { client.EndSend(ar); } } class Program { static void Main(string[] args) { // Start server SocketServer server = new SocketServer(); server.Start(); // Connect client to server SocketClient client = new SocketClient(); client.Connect(); // Send data to server client.Send("Hello, server!"); Console.ReadLine(); } } ``` 这个示例中,我们使用了异步的 BeginReceive 和 BeginSend 方法来在接收和发送数据时不阻塞主线程。在接收数据时,我们先接收到一部分数据,然后判断是否收到了完整的数据,如果没有就继续接收。在发送数据时,我们将要发送的数据转换成字节数组后,使用 BeginSend 方法发送,然后在回调函数中调用 EndSend 方法结束发送。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值