通过虚拟串口和网络UDP进行数据收发的Delphi7, Lazarus, VB6和VisualFreeBasic实践

一、 虚拟串口的建立与应用

在WINDOWS平台上,可使用开源的COM0COM建立虚拟串口对,建好的串口对实质上是两个串口的RX与TX互接,向其中的一个端口发送数据,则可以在另一个端口上接收。比如建了COM3和COM4一对虚拟串口,在windows平台的设备管理列表上看到的是下面的样子,使用起来和真实串口几乎无异,用它进行不同应用程序间的数据收发是比较方便的。

1 用VB6的MSCOMM发送数据

程序运行时每秒向串口3发送数据

完整程序代码

vbnet 复制代码
Option Explicit

Private Sub Command1_Click()
    On Error Resume Next
    Dim iComNo As Integer
    iComNo = Val(Text1.Text)
    If MSComm1.PortOpen = False Then
       MSComm1.CommPort = iComNo
       MSComm1.Settings = "9600,N,8,1"
       MSComm1.PortOpen = True
    End If
    MSComm1.Output = Time$ + " --- " + Text2.Text
End Sub

Private Sub Form_Close()
    On Error Resume Next
    If MSComm1.PortOpen = True Then
       MSComm1.PortOpen = False
    End If
End Sub

Private Sub Timer1_Timer()
    On Error Resume Next
    Command1_Click
End Sub

2 用Delphi7安装MSCOMM接收数据

Delphi7完整代码

Delphi 复制代码
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, OleCtrls, MSCommLib_TLB;

type
  TForm1 = class(TForm)
    MSComm1: TMSComm;
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure MSComm1Comm(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  ComNo, ErrCode: integer;
  handle: hwnd;
begin
  val(Edit1.Text, ComNo, ErrCode);
  try
  MSComm1.CommPort := ComNo;
  MSComm1.RThreshold := 1;
  MSComm1.PortOpen := True;
  except
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if MSComm1.PortOpen = True then
     MSComm1.PortOpen := False;
end;

procedure TForm1.MSComm1Comm(Sender: TObject);
  var
  sMyString: string;
begin
  if MSComm1.CommEvent = 2 then
    Listbox1.Items.Insert (0, MSComm1.Input);
  if Listbox1.Items.Count >= 100 then
    ListBox1.Items.Delete(100);
end;

end.

3 用Delphi7安装SPComm接收数据

Delphi7完整代码

Delphi 复制代码
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SPComm;

type
  TForm1 = class(TForm)
    Comm1: TComm;
    Edit1: TEdit;
    Label1: TLabel;
    ListBox1: TListBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
   ComNo: integer;
   ErrCode: integer;
begin
  Val(Edit1.Text, ComNo, ErrCode);
  Comm1.CommName := 'COM' + Trim(IntToStr(ComNo));
  try
    Comm1.StartComm;
  except
  end;
end;

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
begin
  ListBox1.Items.Insert(0, PAnsiChar(Buffer));
  if ListBox1.Items.Count >=100 then
    ListBox1.Items.Delete(100);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  try
    Comm1.StopComm;
  except
  end;
end;

end.

4 用Lazarus安装SPComm接收数据

程序代码和Delphi7安装SPComm完全一样。

二、 基于UDP的数据传送

以VB6和勇芳VisualFreeBasic编程为例。

1 用VB6加winsock发送udp数据

VB6加上部件Winsock如下图,再放一个Timer,定时间隔1000毫秒,按Command1按钮。

Winsock属性设置

完整VB6程序代码

vbnet 复制代码
Option Explicit

Private Sub Command1_Click()
    Winsock1.SendData (Time$)
End Sub

Private Sub Timer1_Timer()
    Command1_Click
End Sub

2 用勇芳VisualFreeBasic的udp接收数据

窗体上放上Network控件,Text2,和Command2。Text1和Command1留在上面没用。

Network1属性设置如下图。

完整程序代码(标注全部是勇芳VisualFreeBasic默认的)

vbnet 复制代码
'这是标准的工程模版,你也可做自己的模版。
'写好工程,复制全部文件到VFB软件文件夹里【template】里即可,子文件夹名为 VFB新建工程里显示的名称
'快去打造属于你自己的工程模版吧。

Dim Shared hwndnetwk1 As hwnd

Sub Form1_Command1_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)
    'Network1.UdpPostData("127.0.0.1",2000,"abcd")
End Sub

Sub Form1_Command2_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)
   
End Sub

'[Form1]事件 : 即将关闭窗口,返回非0可阻止关闭
'hWndForm  当前窗口的句柄(WIN系统用来识别窗口的一个编号,如果多开本窗口,必须 Me.hWndForm = hWndForm 后才可以执行后续操作本窗口的代码)
Function Form1_WM_Close(hWndForm As hWnd) As LResult
   'hwndnetwk1 = Network1.UdpClose
   Function = FALSE ' 返回 TRUE 阻止关闭窗口。
End Function

'[Form1]事件 : 完成创建窗口及所有的控件后,此时窗口还未显示。注:自定义消息里 WM_Create 此时还未创建控件和初始赋值。
'hWndForm  当前窗口的句柄(WIN系统用来识别窗口的一个编号,如果多开本窗口,必须 Me.hWndForm = hWndForm 后才可以执行后续操作本窗口的代码)
'UserData  来自显示窗口最后1个参数,例: Form2.Show(父窗口句柄,模式,UserData)
Sub Form1_WM_Create(hWndForm As hWnd,UserData As Integer)
   'hwndnetwk1 = Network1.UdpOpen
End Sub

'[Form1.Network2]事件 : UDP接收到新数据
'hWndForm    当前窗口的句柄(WIN系统用来识别窗口的一个编号,如果多开本窗口,必须 Me.hWndForm = hWndForm 后才可以执行后续操作本窗口的代码)
'UDP通信,只管发送数据给对方,不管对方有没收到,可能会发生丢包的事情,优点是速度快。
' ***** 要想接收数据,必须启用UDP通信服务 *****
'nn.ip        As String '对方的IP地址
'nn.Port      As UShort '对方的端口
'nn.Dat       As String '收到的数据(是数据不一定是文本),最多4096字节
Sub Form1_Network2_UdpNewData(hWndForm As hWnd, nn As Network_Data)
   Print "接收数据,内容:" , nn.Dat '非文本数据不要打印
  '假如是数据可以用 For i=0 To Len(nn.Dat)-1 :nn.Dat[i] :Next 读取每个字节
  '还可以用 Network1.UdpPostData(nn.ip,nn.Port,"数据") 发给对方数据
  Text1.text = nn.Dat
End Sub

'[Form1.Network1]事件 : UDP接收到新数据
'hWndForm    当前窗口的句柄(WIN系统用来识别窗口的一个编号,如果多开本窗口,必须 Me.hWndForm = hWndForm 后才可以执行后续操作本窗口的代码)
'UDP通信,只管发送数据给对方,不管对方有没收到,可能会发生丢包的事情,优点是速度快。
' ***** 要想接收数据,必须启用UDP通信服务 *****
'nn.ip        As String '对方的IP地址
'nn.Port      As UShort '对方的端口
'nn.Dat       As String '收到的数据(是数据不一定是文本),最多4096字节
Sub Form1_Network1_UdpNewData(hWndForm As hWnd, nn As Network_Data)
   Print "接收数据,内容:" , nn.Dat '非文本数据不要打印
  '假如是数据可以用 For i=0 To Len(nn.Dat)-1 :nn.Dat[i] :Next 读取每个字节
  '还可以用 Network1.UdpPostData(nn.ip,nn.Port,"数据") 发给对方数据
   Text2.text = nn.Dat
End Sub

程序使用的2000端口在本机防火墙上打开,WIN11下程序运行时自动会提示是否要打开,点确认即自动打开。两个程序运行后,VB6自动向VisualFreeBasic发送数据,不用握手,直接往UDP端口送数据。在本机上和本地网络上使用是一样的。

实践习练程序放在CSDN链接里了

【免费】UART和UDP数据传送习练实践例程资源-CSDN下载

相关推荐
我也要当昏君4 小时前
6.5 万维网(答案见原书P294)
网络
嶔某4 小时前
网络:传输层协议UDP和TCP
网络·tcp/ip·udp
文火冰糖的硅基工坊4 小时前
[嵌入式系统-154]:各种工业现场总线比较
网络·自动驾驶·硬件架构
以己之4 小时前
详解TCP(详细版)
java·网络·tcp/ip
Ronin3055 小时前
【Linux网络】封装Socket
linux·网络·socket·网络通信
Brianna Home5 小时前
博客安全攻防演练:从攻击者视角构筑铜墙铁壁
网络·数据库·安全·oracle
Jewel Q6 小时前
OSPF 组播地址
网络·智能路由器
haierccc7 小时前
从IP地址和子网掩码判断该地址属于哪个网段
网络
星哥说事7 小时前
网络监控工具:ping、traceroute、nmap、Wireshark 网络探测与分析
网络·测试工具·wireshark