C#socket通讯使用方法
C#socket通讯,三秒重连,无限次数,每次执行完方法都会判断是否断开连接,断开就会执行连接方法,并且捕获发生的异常,连接后会向对方发送连接成功信息。
接收发送来的socket数据,二字节转换成string,再转成json对象,方便调用,创建变量接收传递的数据,根据传递的数据智行对应的方法,并将结果通过socket传输。
写两个代码示例
一个是接收输出参数,并返回结果
一个是传递参数获取执行结果
代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Net;
using System.Windows.Forms;
using System.Threading;
using Newtonsoft.Json;
using System.Runtime.InteropServices;
using System.Reflection;
using Newtonsoft.Json.Linq;
using System.Xml.Linq;
using System.CodeDom.Compiler;
using System.Net.NetworkInformation;
namespace NW_Fk
{
//调用函数前需先调用ConnectPower()和ConnectRefMeter()函数初始化参数。
public class SocketTest
{
//定义需要用到的属性
private const int RetryDelay = 3000; // 重试延迟(毫秒)
private static int retryCount = 0;//重连次数
private static bool isConnected = false;//连接状态
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static int port = 278;//定义端口号
private static IPAddress ipAdd = IPAddress.Parse("127.0.0.1");//初始化ip地址
private static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化socket链接
private static NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();// 获取本机的所有网络接口
public static void threadSocket()
{
// 创建一个线程池,用于多线程处理
ThreadPool.SetMinThreads(10,10);
// 创建多个socket连接
//for (int i = 1; i <= 5; i++){
//启动socket
Thread t = new Thread(new ParameterizedThreadStart(StartSocket));
t.Start();
//}
Console.ReadLine();
}
static void StartSocket(object id){
// 遍历每个网络接口
foreach (NetworkInterface networkInterface in networkInterfaces){
// 判断是否为以太网接口
if (networkInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet){
// 获取网络接口的 IP 属性集合
IPInterfaceProperties ipProperties = networkInterface.GetIPProperties();
// 获取该网络接口的 IPv4 地址集合
UnicastIPAddressInformationCollection ipAddresses = ipProperties.UnicastAddresses;
// 遍历 IPv4 地址集合
foreach (UnicastIPAddressInformation ipAddress in ipAddresses)
{
// 判断是否为 IPv4 地址
if (ipAddress.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
//将ip地址赋值给全局静态变量ipAdd
ipAdd = ipAddress.Address;
}
}
}
}
while (true) {
while (isConnected == false)
{
//捕获连接异常,当异常时,延迟三秒进行下一次链接,完成连接将isConnected 变为 true
try
{
socket.Close();// Socket 断开连接
Thread.Sleep(RetryDelay);// 延迟时间
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 重新创建 Socket 实例并连接
Console.WriteLine("ip地址和端口号为:" + ipAdd + ":" + port);
socket.Connect(new IPEndPoint(ipAdd, port));//执行失败会爆SocketException异常,由catch捕获,并重新连接
isConnected = true;//将连接状态修改为已连接 true
byte[] resultOk = Encoding.UTF8.GetBytes(ipAdd + ":" + port + "OK!!!!!");
socket.Send(resultOk);//向socket发送连接成功
Console.WriteLine("连接成功");
retryCount = 0;
}
catch (SocketException)
{
// 连接失败,进行重试
Console.WriteLine("连接失败第" + retryCount + "次重试...");
isConnected = false;
retryCount++;
//每次链接睡眠三秒
System.Threading.Thread.Sleep(RetryDelay);
}
}
//连接完成后将 isConnected 变为true 执行下面方法
while (isConnected == true)
{
try
{
byte[] buffer = new byte[1024];//创建byte数组
int bytesRead = socket.Receive(buffer);// 接收数据
// 将接收到的字节数组转换为字符串
string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
// 解析JSON字符串
var jsonObject = JObject.Parse(receivedData);
// 获取MethodName
string methodName = jsonObject["MethodName"].ToString();
// 获取JsonDarams中的参数值
JObject jsonParams = (JObject)jsonObject["JsonDarams"];
Console.WriteLine(methodName);
//接收输出参数,并返回结果
if (methodName == "方法名")
{
//定义对应类型的变量
float[] intvalue = { };
//获取执行结果(out intvalue 代表输出参数)
int 定义参数输出= 类名.方法(out intvalue);
// 打印执行结果
Console.WriteLine("返回结果()--->>> " + 定义参数输出);
//定义json嵌套格式(如果需要修改返回的json格式,可以修改一下结构)
string json = @"
{
""MethodName"": """",
""data"": {
""result"": """"
}
}";
//将嵌套格式转成json对象
JObject jsonObj = JObject.Parse(json);
//定义methodName
string MethodName = (string)jsonObj["MethodName"];
//如果需要将执行结果也返回,则可以将results也放到下面的定义属性值里面
//int results = (int)jsonObj["data"]["results"];
//定义内层 dataObj 的 results 属性值(在new JObject(results))
JObject dataObj = new JObject(
new JProperty("result", intvalue)
);
//定义外层json属性值
JObject outObj = new JObject(
new JProperty("MethodName", methodName),
new JProperty("data", dataObj)
);
string Json = outObj.ToString();
// 发送执行结果到客户端
byte[] resultBytes = Encoding.UTF8.GetBytes(Json);
socket.Send(resultBytes);
}
//传递参数获取执行结果
else if (methodName == "方法名")
{
//定义变量接收json传递过来的参数
bool[] meterPosition = jsonParams["MeterPosition"].ToObject<bool[]>();
//获取执行结果
int powerOn = 类名.方法名(meterPosition);
// 打印执行结果
Console.WriteLine("PowerOn()--->>> " + powerOn);
//定义json嵌套格式
string json = @"
{
""MethodName"": """",
""data"": {
""result"": """"
}
}";
//将嵌套格式转成json对象
JObject jsonObj = JObject.Parse(json);
string MethodName = (string)jsonObj["MethodName"];
//int results = (int)jsonObj["data"]["results"];
//定义内层 dataObj 的 results 属性值
JObject dataObj = new JObject(
new JProperty("result", powerOn)
);
//定义外层json属性值
JObject outObj = new JObject(
new JProperty("MethodName", methodName),
new JProperty("data", dataObj)
);
string Json = outObj.ToString();
// 发送执行结果到客户端
byte[] resultBytes = Encoding.UTF8.GetBytes(Json);
socket.Send(resultBytes);
}
}
//当上面的方法出现异常后,执行cache方法
catch (SocketException)
{
// 连接失败,进行重试
Console.WriteLine("连接失败第" + retryCount + "次重试...");
isConnected = false;
retryCount++;
//每次链接睡眠三秒
System.Threading.Thread.Sleep(RetryDelay);
}
catch (NullReferenceException)
{
Console.WriteLine("出现了NullReferenceException");
byte[] resultOk = Encoding.UTF8.GetBytes("出现了NullReferenceException");
socket.Send(resultOk);
}
catch (JsonReaderException)
{
byte[] resultOk = Encoding.UTF8.GetBytes("出现了JsonReaderException");
socket.Send(resultOk);
Console.WriteLine("出现了JsonReaderException");
}
}
}
}
}
}