当前位置: 首页 > news >正文

C#与FX5U进行Socket通信

实现效果

实现步骤:

注意:详细的参数这里就不说明了,自己网上搜即可;

打开GX Works3 创建FX5U项目

系统参数设置PLC的具体型号(我有实物PLC)

设置IP及组态参数

添加通讯设备(这里PLC做客户端,因此添加:Active连接设备);

设置PLC的端口号、服务器IP、服务器端口号;

当前添加的设备No为1,记住这个参数,后面程序要输入;

配置完后点击应用并下载到PLC,下载完要重启PLC;

下面不废话,直接上PLC程序;

重点:

在线监控数据

监控D1300是通讯接收数据的起始地址,同时它还存储对方使用了多少个字节发送数据过来;那么我们要截取数据就要从D1301及以后开始截;

还看到PC只发了5个字符,但是收到却多了一位(发:SN123;收:SN1239);那么就要处理一下;把多余的字符删掉;

本项目案例把收到的数据又传回给PC;经过上面的处理已经拿到完整的数据了,然后置位一下M11就能把数据发给PC,注意每次发送都要触发一下M11,可以自己改成自动发送;

C#部分

创建一个页面 SocketPage.xaml

页面代码

<Page x:Class="WpfApp4.Views.SocketPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp4.Views"mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="650"Title="SocketPage" ><Grid><Grid.ColumnDefinitions><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="35"/><RowDefinition Height="35"/><RowDefinition Height="35"/><RowDefinition/></Grid.RowDefinitions><StackPanel Orientation="Horizontal" Grid.Row="0"><Border Height="30" Width="100" Background="White"><TextBlock Text="状态显示"  FontSize="20"   VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black"/></Border><Border Height="30" Width="500" Background="#FF0ABEFF"><TextBlock Text="欢迎使用该软件" x:Name="txtb_serverData" FontSize="20"   VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/></Border></StackPanel><StackPanel Orientation="Horizontal" Grid.Row="1"><Border Height="30" Width="100" Background="White"><TextBlock Text="读取信息"  FontSize="20"   VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black"/></Border><Border Height="30" Width="500" Background="#FF0ABEFF"><TextBlock Text="------" x:Name="txtb_reData" FontSize="20"   VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/></Border></StackPanel><StackPanel Orientation="Horizontal" Grid.Row="2"><Border Height="30" Width="100" Background="White"><TextBlock Text="连接设备"  FontSize="20"   VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black"/></Border><Border Height="30" Width="500" Background="#FF0ABEFF"><TextBlock Text="127.0.0.0:888" x:Name="txtb_ConnentDevice" FontSize="20"   VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/></Border></StackPanel><StackPanel Orientation="Horizontal" Grid.Row="3"><GroupBox Header="服务器与PLC通讯" Width="250" Height="150"  FontSize="20" BorderBrush="#FF0ABEFF" BorderThickness="2"><Grid><Grid.ColumnDefinitions><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition/><RowDefinition/><RowDefinition/></Grid.RowDefinitions><StackPanel VerticalAlignment="Center"   Orientation="Horizontal"  Grid.Row="0"><Border HorizontalAlignment="Left" ><TextBlock Text="服务器IP: "   /></Border><Border HorizontalAlignment="Right" ><TextBox Text="192.168.2.223" x:Name="txb_ServerAdderess" VerticalAlignment="Center"  TextAlignment="Center" FontSize="16" Width="145"/></Border></StackPanel><StackPanel VerticalAlignment="Center"   Orientation="Horizontal"  Grid.Row="1"><Border HorizontalAlignment="Left" ><TextBlock Text="端口号: "   /></Border><Border HorizontalAlignment="Right"><TextBox Text="8000" x:Name="txb_Prot" Width="100" TextAlignment="Center"/></Border></StackPanel><Border Grid.Row="2" Width="150" Height="30"><Button x:Name="btn_OpenConnent" Content="打开服务器"  Click="Button_OpenProtClick"/></Border></Grid></GroupBox><GroupBox Header="写数据给PLC" Width="250" Height="150"  FontSize="20" BorderBrush="#FF0ABEFF" BorderThickness="2"><Grid><Grid.ColumnDefinitions><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition/><RowDefinition/><RowDefinition/></Grid.RowDefinitions><StackPanel VerticalAlignment="Center"   Orientation="Horizontal"  Grid.Row="0"><Border HorizontalAlignment="Left" ><TextBlock Text="开   头: "   Width="70"/></Border><Border HorizontalAlignment="Right" ><TextBox Text="SN" x:Name="txb_WriteSN" VerticalAlignment="Center"  TextAlignment="Center" FontSize="16" Width="145"/></Border></StackPanel><StackPanel VerticalAlignment="Center"   Orientation="Horizontal"  Grid.Row="1"><Border HorizontalAlignment="Left" ><TextBlock Text="序列号: "   Width="70"/></Border><Border HorizontalAlignment="Right"><TextBox Text="123456789" x:Name="txb_WriteNume" Width="145" TextAlignment="Center" FontSize="16"/></Border></StackPanel><Border Grid.Row="2" Width="150" Height="30"><Button x:Name="btn_WriteDevice" Content="写入"  Click="btn_WriteDevice_Click"/></Border></Grid></GroupBox></StackPanel></Grid>
</Page>

页面后台代码

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;namespace WpfApp4.Views
{/// <summary>/// SocketPage.xaml 的交互逻辑/// </summary>public partial class SocketPage : Page{public SocketPage(){InitializeComponent();}/// <summary>/// 打开/关闭连接/// </summary>bool isConnent = false;/// <summary>/// 服务器已创建/// </summary>bool isOpenConnent = false;/// <summary>/// 触发写入/// </summary>bool btn_Write = false;//第一步:调用socket()函数创建一个用于通信的套接字private Socket listenSocket;//字典集合:存储IP和Socket的集合private Dictionary<string, Socket> OnLineList = new Dictionary<string, Socket>();//编码格式Encoding econding = Encoding.Default;private void Button_OpenProtClick(object sender, EventArgs e){if (isConnent){MessageBox.Show("服务器已开启,请勿重复点击!");return;}if (!isOpenConnent){//第一步:调用socket()函数创建一个用于通信的套接字listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);isOpenConnent = true;}//第二步:给已经创建的套接字绑定一个端口号,这一般通过设置网络套接口地址和调用Bind()函数来实现IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(this.txb_ServerAdderess.Text.Trim()), int.Parse(this.txb_Prot.Text.Trim()));try{listenSocket.Bind(endPoint);}catch (Exception ex){MessageBox.Show("服务器开启失败:" + ex.Message, "开启服务器");//listenSocket.Shutdown(SocketShutdown.Both);//listenSocket.Close();//MessageBox.Show("关闭服务器中......");isOpenConnent = false;return;}//第三步:调用listen()函数使套接字成为一个监听套接字listenSocket.Listen(10);//ShowMessage("服务器开启成功");MessageBox.Show("服务器开启成功");isConnent = true;this.Dispatcher.Invoke(new Action(() =>{txtb_serverData.Text = "服务器开启成功!等待客户端连接中......";btn_OpenConnent.Background = new SolidColorBrush(Colors.Green);}));if (isOpenConnent){//开启一个线程监听Task.Run(new Action(() =>{ListenConnection();}));}}private void ListenConnection(){try{while (true){Socket clientSocket = listenSocket.Accept();string ip = clientSocket.RemoteEndPoint.ToString();//MessageBox.Show(ip + "上线了");this.Dispatcher.Invoke(new Action(() =>{txtb_ConnentDevice.Text = "当前连接设备:" + ip;}));Task.Run(() => ReceiveMsg(clientSocket));Task.Run(() => WriteDeviceMsg(clientSocket));}}catch (Exception){throw;}}/// <summary>/// 接收方法/// </summary>/// <param name="clientSocket"></param>private void ReceiveMsg(Socket clientSocket){try{//    // 接收数据byte[] bytesToUse = new byte[60];int numberOfBytesRec = clientSocket.Receive(bytesToUse);string returndata = Encoding.ASCII.GetString(bytesToUse, 0, numberOfBytesRec);//Console.WriteLine("从客户端收到: " + returndata);this.Dispatcher.Invoke(new Action(() =>{txtb_serverData.Text = "从客户端收到: " + returndata;}));while (true){numberOfBytesRec = clientSocket.Receive(bytesToUse);returndata = Encoding.ASCII.GetString(bytesToUse, 0, numberOfBytesRec);Thread.Sleep(10);this.Dispatcher.Invoke(new Action(() =>{txtb_reData.Text = returndata;txtb_serverData.Text = "从客户端收到: " + returndata;}));//Console.WriteLine("从客户端收到: " + returndata);Thread.Sleep(1000);}}catch (Exception ex){MessageBox.Show("接收报错:" + ex.Message);}}private void WriteDeviceMsg(Socket clientSocket){// 发送数据回客户端string response = "Hello from server";byte[] msg = Encoding.ASCII.GetBytes(response);try{while (true){this.Dispatcher.Invoke(new Action(() =>{response = txb_WriteSN.Text.ToString() + txb_WriteNume.Text.ToString();msg = Encoding.ASCII.GetBytes(response);}));if (btn_Write){clientSocket.Send(msg);//Console.WriteLine("发送到客户端: " + response);btn_Write = false;}Thread.Sleep(1000);}}catch (Exception){throw;}}/// <summary>/// 消息发送/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_WriteDevice_Click(object sender, EventArgs e){btn_Write = true;return;}}
}

注意:要把当前连接PLC的网卡设置成服务器IP

最后启动测试就可以了;

http://www.xdnf.cn/news/1111807.html

相关文章:

  • 【设计模式】桥接模式(柄体模式,接口模式)
  • OneCode 3.0架构深度剖析:工程化模块管理与自治UI系统的设计与实现
  • 企业商业秘密保卫战:经营信息类案件维权全攻略
  • 分布式系统高可用性设计 - 缓存策略与数据同步机制
  • wedo稻草人-----第32节(免费分享图纸)
  • 实验一 接苹果
  • LeetCode经典题解:3、无重复字符的最长子串
  • ADI的EV-21569-SOM核心板和主板转接卡的链接说明
  • Kubernetes持久卷实战
  • 13. G1垃圾回收器
  • os.loadavg()详解
  • Python 训练营打卡 Day 59-经典时序预测模型3
  • Java 大视界 -- Java 大数据机器学习模型在电商用户复购行为预测与客户关系维护中的应用(343)
  • IDEA中一个服务创建多个实例
  • 【C/C++】迈出编译第一步——预处理
  • [案例八] NX二次开发长圆孔的实现(支持实体)
  • TensorFlow2 study notes[2]
  • 【Linux网络】IP 协议详解:结构、地址与交付机制全面解析
  • 算法第三十一天:贪心算法part05(第八章)
  • Qt 多线程编程:单例任务队列的设计与实现
  • 【数据结构初阶】--顺序表(二)
  • 【读书笔记】《C++ Software Design》第一章《The Art of Software Design》
  • 【一起来学AI大模型】RAG系统组件:检索器(LangChain)
  • Python 实战:构建可扩展的命令行插件引擎
  • 试用了10款翻译软件后,我只推荐这一款!完全免费还超好用
  • 挖矿病毒判断与处理 - 入门
  • DBeaver连接MySQL8.0报错Public Key Retrieval is not allowed
  • Redis集群会有写操作丢失吗?为什么?
  • 1. 好的设计原则
  • C++法则21:避免将#include放在命名空间内部。