参考内容:

C#socket通信时,怎样判断socket双方是否断开连接

C#之Socket断线和重连

Socket.Poll 方法

Socket.Blocking 属性

最近需要写个网口通信的上位机程序,我负责写客户端,控制多个客户端与多个服务端简历连接进行通讯,关于异常处理一直有问题,写出来做个记录。

建立连接

/// <summary>
/// 与客户端建立连接:若出错,则开辟一个新线程,在新线程里每隔五秒尝试连接一次,连接成功的话跳出循环,加入到列表中
/// </summary>
private void CreateSocketConnection()
{
int countOfServers = dt_ServerInfo.Rows.Count; //dt表中存着服务端的IP地址和端口号
for (int i = 0; i < countOfServers; i++)
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(dt_ServerInfo.Rows[i]["serverIP"].ToString()),
int.Parse(dt_ServerInfo.Rows[i]["serverPort"].ToString()));
try
{
IAsyncResult result = serverSocket.BeginConnect(serverEndPoint, null, null);
result.AsyncWaitHandle.WaitOne(500);
clientsockets.Add(serverSocket);
socketClients.TryAdd(serverSocket.RemoteEndPoint.ToString(), serverSocket);
}
catch (SocketException) //尝试访问套接字时出错
{
Thread thr_connect = new Thread(() =>
{
try
{
for (int j = 0; j < 10; j++)
{
//serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Connect(serverEndPoint);
DateTime now = DateTime.Now;
while (now.AddSeconds(5) > DateTime.Now) { }
break;
}
clientsockets.Add(serverSocket);
socketClients.TryAdd(serverSocket.RemoteEndPoint.ToString(), serverSocket);
}
catch { }
});
thr_connect.IsBackground = true;
thr_connect.Start();
}
}
}

发送数据

开辟一个线程来专门发送数据:

/*全局变量*/
Thread Thr_Send = null;
volatile bool Stopflag = false; //发送停止标志位 - volatile保证不被优化掉 ...... /*初始化*/
Thr_Send = new Thread(new ThreadStart(SendThread));
Thr_Send.IsBackground = true;
Thr_Send.Start(); /*发送线程内容*/
private void SendThread()
{
while (true)
{
if (!Stopflag)
{
try
{
foreach (var item in socketClients)
{
string serverInfo = item.Key.ToString();
DataRow[] drs = dt_ServerInfo.Select($"ServerIp = '{serverInfo.Split(':')[0]}' And ServerPort = '{serverInfo.Split(':')[1]}'");
byte[] sendByte = hexStringToByteArray(drs[0]["Command"].ToString());
try
{
IAsyncResult result = item.Value.BeginSend(sendByte, 0, sendByte.Length, SocketFlags.None, null, null);
result.AsyncWaitHandle.WaitOne(500);
}
catch (SocketException) // 尝试访问套接字时出错
{
IPEndPoint tempEndpoint = (IPEndPoint)item.Value.RemoteEndPoint;
item.Value.Shutdown(SocketShutdown.Both);
item.Value.Disconnect(true);
item.Value.Close();
Socket tempsocket = item.Value;
socketClients.TryRemove(item.Key, out tempsocket); Thread thr_reconnect = new Thread(() =>
{
try
{
int j = 0;
for (; j < 10; j++)
{
tempsocket.Connect(tempEndpoint);
DateTime now_temp = DateTime.Now;
while (now_temp.AddSeconds(5) > DateTime.Now) { }
break;
}
if (j!=10)
{
socketClients.TryAdd(tempsocket.RemoteEndPoint.ToString(), tempsocket);
}
Thread.CurrentThread.Abort();
}
catch { }
});
thr_reconnect.IsBackground = true;
thr_reconnect.Start();
}
}
DateTime now = DateTime.Now;
while (now.AddSeconds(1) > DateTime.Now) { }
}
catch (Exception ex)
{
throw ex;
}
}
}
}

BeginReceive也是这么写的,就不贴了,我这只处理了客户端程序错误,没有处理上面说的物理问题,我先测测能用不。

心跳检测

这个不会写,不知道对不对

新开了一个线程:

private byte[] GetKeepLiveData()
{
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)3000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); //keep-alive 间隔
BitConverter.GetBytes((uint)500).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); //尝试间隔
return inOptionValues;
} private void CheckAlive()
{
Thread.Sleep(10000);
while (true)
{
try
{
lock (socketClients)
{
foreach (var item in socketClients)
{
//if (item.Client.Client.Poll(500, System.Net.Sockets.SelectMode.SelectRead) && (item.Client.Client.Available == 0)) if (item.Value.Poll(500, System.Net.Sockets.SelectMode.SelectRead) && item.Value.Available == 0)
{
//MaterialMessageBox.Show("未收到心跳检测回复");
//心跳检测处理
item.Value.Shutdown(SocketShutdown.Both);
item.Value.Disconnect(true);
item.Value.Close();
Socket tempsocket = item.Value;
socketClients.TryRemove(item.Key, out tempsocket);
}
}
} }
catch (Exception e)
{
MaterialMessageBox.Show(e.ToString());
}
Thread.Sleep(500);
}
}

C# Socket 通信时,怎样判断 Socket 双方是否断开连接的更多相关文章

  1. socket通信时如何判断当前连接是否断开--select函数,心跳线程,QsocketNotifier监控socket

    client与server建立socket连接之后,如果突然关闭server,此时,如果不在客户端close(socket_fd),会有不好的影响: QsocketNotifier监控socket的槽 ...

  2. centos socket通信时 connect refused 主要是防火墙问题

    centos socket通信时 connect refused 主要是防火墙问题,可以关闭防火墙,或者开放程序中的端口

  3. C#socket通信时,怎样判断socket双方是否断开连接

    我在Server端new了一个socket,然后bind,开了一个线程来accept前来连接的client,每接到一个client前来连接就新开一个线程和它进行通信.我把Server端得到的socke ...

  4. Socket通信时服务端无响应,客户端超时设置

    背景:在写一个客户端的socket程序,服务端没有返回消息,客户端一直在等待. 目标:我需要设置一个时间,如果超过这个时间客户端自动断开连接.最好是在服务端实现,客户端对我来说不可控.

  5. 解决在进行socket通信时,一端输出流OutputStream不关闭,另一端输入流就接收不到数据

    输出的数据需要达到一定的量才会向另一端输出,所以在传输数据的末端添加 \r\n 可以保证不管数据量是多少,都立刻传输到另一端.

  6. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  7. 【转】C# Socket通信编程

    https://www.cnblogs.com/dotnet261010/p/6211900.html#undefined 一:什么是SOCKET socket的英文原义是“孔”或“插座”.作为进程通 ...

  8. 使用 AT 指令进行 Socket 通信

    BC26 支持使用 Socket 进行 TCP 和 UDP 协议通信,这两个协议也是 BC26 支持的众多通信协议的基础.本文讲解如何使用这两个协议与服务器端进行通信.在学习这篇文章前,请首先使用AT ...

  9. 基于TCP与UDP协议的socket通信

    基于TCP与UDP协议的socket通信 C/S架构与初识socket 在开始socket介绍之前,得先知道一个Client端/服务端架构,也就是 C/S 架构,互联网中处处充满了 C/S 架构(Cl ...

  10. .net平台下C#socket通信(中)

    上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次 ...

随机推荐

  1. 关于解决 inittramfs unpacking failed:Decoding failed 报错

    解决办法 vi /etc/initramfs-tools/initramfs.conf 更改COMPRESS=lz4以COMPRESS=gzip 保存更改 sudo update-initramfs ...

  2. 基于.net C# Socket WinForm MQTT 客户端开发

    1.什么是MQTT? MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的&quo ...

  3. 【Java SE进阶】Day09 字节流、字符流、I/O操作、属性集

    一.I/O概述 1.输入输出 输入:硬盘-->内存 输出:内存-->内存 2.流 字节流:一个字节等于8位 字符流:一个字符=2个字节 二.字节流 1.概述 以字节的方式读取/传输 可以读 ...

  4. 线上服务异常的定位、处理与优化的探索 - 第三章 Java虚拟机

    Java虚拟机   之所以引入关于JVM的篇章,是发现多数项目发生的线上问题很大的几率源自JVM调优配置不当引起.对JVM的内存模型.GC垃圾回收机制.调优方式有一个系统化的了解后,可以快速处理或避免 ...

  5. 漫谈计算机网络:番外篇 ------网络安全相关知识——>公钥与私钥、防火墙与入侵检测

    <漫谈计算机网络>上次已经完结啦,今天出一个番外篇! 2022-12-06 今天我们来聊一聊网络安全 废话不多说直接进入正题 网络安全问题概述 计算机网络面临的安全性威胁 两大类威胁:被动 ...

  6. Doris安装部署

    下载安装 Doris运行在Linux环境中,推荐 CentOS 7.x 或者 Ubuntu 16.04 以上版本,同时你需要安装 Java 运行环境(JDK最低版本要求是8) 1.下载安装包 下载地址 ...

  7. WinUI(WASDK)使用MediaPipe检查手部关键点并通过ML.NET进行手势分类

    前言 之所以会搞这个手势识别分类,其实是为了满足之前群友提的需求,就是针对稚晖君的ElectronBot机器人的上位机软件的功能丰富,因为本来擅长的技术栈都是.NET,也刚好试试全能的.NET是不是真 ...

  8. kestrel网络编程--开发redis服务器

    1 文章目的 本文讲解基于kestrel开发实现了部分redis命令的redis伪服务器的过程,让读者了解kestrel网络编程的完整步骤,其中redis通讯协议需要读者自行查阅,文章里不做具体解析. ...

  9. [论文总结] kmeans聚类和WGCNA

    kmeans聚类和WGCNA 文章目录 kmeans聚类和WGCNA 论文1 论文2 论文3 总结 总结了3篇论文中kmeans聚类和WGCNA的运用. 论文1 Comprehensive disse ...

  10. [编程基础] Python装饰器入门总结

    Python装饰器教程展示了如何在Python中使用装饰器基本功能. 文章目录 1 使用教程 1.1 Python装饰器简单示例 1.2 带@符号的Python装饰器 1.3 用参数修饰函数 1.4 ...