在Delphi中关于UDP协议的实现
首先我把UDP无连接协议的套接字调用时序图表示出来

在我把在Delphi中使用UDP协议实现数据通讯收发的实现方法总结如下:
例子描述:下面例子是我的一个实际设备通讯的例子,使用UDP协议在4660端口上发送'F1,00'(16进制,2个字节),在同一个端口上接收到'F1,00,00,00,00,00'((16进制,2个字节))
1.使用底层函数来实现
procedure TForm1.FormCreate(Sender: TObject);
var
WSAData:TWSAData;
begin
edtHost.Text:=192.168.1.222';
edtPort.Text:='4660';
//1.初始化Winsock
if (WSAStartup(MAKEWORD(2,0),WSAData)<>0) then
begin
//初始化失败
memInfo.Lines.Add('Winsock Init Failed');
exit;
end
else
memInfo.Lines.Add('Socket Start');
end;
procedure TForm1.btnFingerClick(Sender: TObject);
var
Info:string;
BufSend,BufRecv:array[0..1024] of byte;
skt:TSOCKET;
addr:TSockAddr;
Re:Integer;
S:String;
i:Integer;
begin
//=====================数据发送=========================================
//2.建立socket
skt:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(skt=INVALID_SOCKET)then
begin
memInfo.Lines.Add('Error:Create socket failed!');
exit;
end;
//3.连接主机
ZeroMemory(@addr,sizeof(addr));
addr.sin_family :=AF_INET;
addr.sin_addr.s_addr :=inet_addr('192.168.1.222');
addr.sin_port:=htons(4660);
Re := connect(skt,addr,sizeof(addr));
if(Re<>0)then
begin
memInfo.Lines.Add('Connect to server failed');
exit;
end;
//4.发送信息
BufSend[0]:=$F1;
BufSend[1]:=0;
Re:=send(skt,BufSend,2,0);
if(Re=SOCKET_ERROR)then
begin
memInfo.Lines.Add('Send Data Failed');
exit;
end;
//6.关闭socket
closesocket(skt);
//=============接收数据的==================================
//2.建立socket
skt:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(skt=INVALID_SOCKET)then
begin
memInfo.Lines.Add('Error:Create socket failed!');
exit;
end;
//3.绑定主机
ZeroMemory(@addr,sizeof(addr));
addr.sin_family :=AF_INET;
addr.sin_addr.s_addr :=inet_addr('192.168.1.106');
addr.sin_port:=htons(4660);
Re := Bind(skt,addr,sizeof(addr));
if(Re<>0)then
begin
memInfo.Lines.Add('Connect to server failed');
exit;
end;
//4.接收信息
Re:=Recv(skt,BufRecv,6,0);
if(Re=SOCKET_ERROR)then
begin
memInfo.Lines.Add('Send Data Failed');
exit;
end
else
begin
S:='';
for i:=0 to Re-1 do
begin
S:=S+IntToHex(Integer(BufRecv[i]),2);
end;
memInfo.Lines.Add(S);
end;
//6.关闭socket
closesocket(skt);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
//6.释放Winsock
WSACleanUP();
end;
2.使用TUDPSocket组件实现
TUDPSocket组件是继承于TCustomIPClient的。它被设计为只能当作一个客户端来用
所以它是不能直接用来接收数据的,要是实现接收必须另外定义一个接收的TIPSocket,重新绑定接口.
type
TForm2 = class(TForm)
UdpSocket1: TUdpSocket;
Button1: TButton;
UdpSocket2: TUdpSocket;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
aUDPServer:TIPSocket;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
var
addr:sockAddr_In;
begin
UdpSocket1.RemoteHost:='192.168.1.222';
UdpSocket1.RemotePort:='4660';
UdpSocket1.Open ;
aUDPServer:=TIPSocket.Create(nil);
aUDPServer.RemoteHost:='192.168.1.222';
aUDPServer.RemotePort:='4660';
aUDPServer.LocalHost:=aUDPServer.LocalHostName;
aUDPServer.LocalPort:='4660';
aUDPServer.Protocol:=IPPROTO_UDP;
aUDPServer.SockType:=stDgram;
aUDPServer.Active:=true;
addr:=aUDPServer.GetSocketAddr(aUDPServer.LocalHost,aUDPServer.LocalPort);
bind(aUDPServer.Handle,addr,sizeof(addr));
end;
procedure TForm2.Button1Click(Sender: TObject);
var
ReceivedString:string;
Buff:array[0..1] of byte;
RevBuf:array[0..1024] of byte;
RevSize:Integer;
i:Integer;
S:string;
ToAddr:sockAddr_In;
Len:integer;
a:in_Addr;
begin
Buff[0]:=$F1;
Buff[1]:=0;
UdpSocket1.SendBuf(Buff,2);
ToAddr:=UdpSocket2.GetSocketAddr(UdpSocket2.LocalHost,UdpSocket2.LocalPort);
bind(UdpSocket2.Handle,ToAddr,sizeof(ToAddr));
RevSize:=UdpSocket2.ReceiveBuf(RevBuf,6) ;
S:='';
for i:=0 to RevSize-1 do
begin
S:=S+IntToHex(Integer(RevBuf[i]),2);
end;
ShowMessage(S);
end;
3.使用TIdUDPClient组件实现
TIdUDPClient组件中重新绑定了一个Socket,用来专门接收数据,所以本身一个组件就可以实现接收
procedure TForm1.Button1Click(Sender: TObject);
var
ReceivedString:string;
Buff:array[0..1] of byte;
RevBuf:array[0..1024] of byte;
RevSize:Integer;
i:Integer;
S:string;
begin
Buff[0]:=$F1;
Buff[1]:=0;
IdUDPClient1.SendBuffer(Buff,2);
RevSize:=IdUDPClient1.Binding.Recv(RevBuf,6,0);
S:='';
for i:=0 to RevSize-1 do
begin
S:=S+IntToHex(Integer(RevBuf[i]),2);
end;
ShowMessage(S);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
IdUDPClient1.Host:='192.168.1.222';
IdUDPClient1.Binding.Port:=4660;
IdUDPClient1.Binding.Bind;
IdUDPClient1.Active:=True;
end;
3.使用TNMUDP组件实现
这里我发现在第一次运行时,要连续按两次按钮,才能收到数据
procedure TForm1.BitBtn2Click(Sender: TObject);
var
Buf:array[0..1] of char;
RevBuf :array[0..1024] of char;
ss:string;
i:integer;
Len:Integer;
begin
Buf[0]:=char($F1);
Buf[1]:=char(0);
NMUDP1.SendBuffer(Buf[0],2);
NMUDP1.ReadBuffer(RevBuf[0],Len);
if Len>0 then
begin
ss:='';
for i:=1 to Len do
begin
ss:=ss + intToHex(integer(RevBuf[i]),2);
end;
ShowMessage(ss);
end;
end;
http://blog.sina.com.cn/s/blog_562349090101dizl.html
在Delphi中关于UDP协议的实现的更多相关文章
- Java中的UDP协议编程
一. UDP协议定义 UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包.在OSI模型中,在第四层——传输层,处于IP协议的上一层.UDP有不提供数据报分组.组装和不能对数据包 ...
- TwinCAT 3中基于UDP协议通讯的C++实现
因为项目需要,学习了TwinCAT3中使用UDP协议进行通讯的基本知识.这个做个简单的笔记,方便以后查询. 1 概述 倍福为了实现从实时环境中直接访问网卡(network cards)专门提供了一个函 ...
- 聊聊iOS中TCP / UDP 协议
TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于 传输层协议. UDP(User Datagram protoco ...
- 在Java中实现UDP协议编程(DatagramSocket/DatagramPacket)
1.什么是UDP协议? UDP( User Datagram Protocol )协议是用户数据报,在网络中它与TCP协议一样用于处理数据包.在OSI模型中,在第四层——传输层,处于IP协议的上一层. ...
- Python中的UDP协议应用之飞秋应用-单IP版本
UDP协议是无连接的.不稳定的网络通信协议. 通过使用飞秋端口(2425),以及模拟飞秋消息格式实现使用UDP协议对飞秋进行通信. 飞秋通信格式: '1:1000:66:%s:32:%s' 以冒号分割 ...
- 谈Delphi中SSL协议的应用(好多相关文章)
摘要:本文主要介绍如何在Delphi中使用SSL协议.一共分为七个部分:(1)SSL协议是什么?(2)Delphi中如何使用SSL协议?(3)SSL客户端编程实例.(4)SSL服务端编程实例.(5)S ...
- 老陈---谈Delphi中SSL协议的应用[转]
摘要:本文主要介绍如何在Delphi中使用SSL协议.一共分为七个部分:(1)SSL协议是什么?(2)Delphi中如何使用SSL协议?(3)SSL客户端编程实例.(4)SSL服务端编程实例.(5)S ...
- Python中的端口协议之基于UDP协议的通信传输
UDP协议: 1.python中基于udp协议的客户端与服务端通信简单过程实现 2.udp协议的一些特点(与tcp协议的比较) 3.利用socketserver模块实现udp传输协议的并 ...
- [深入浅出WP8.1(Runtime)]Socket编程之UDP协议
13.3 Socket编程之UDP协议 UDP协议和TCP协议都是Socket编程的协议,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议.UDP适用于一次只 ...
随机推荐
- linux服务器集群重复批量操作脚本实现
http://blog.csdn.net/flyinmind/article/details/8074863 在服务器集群的维护中,经常会遇到同样的操作重复执行很多遍的情况,“登录服务器->做 ...
- storm 经常使用类
弄 <dependency> <groupId>org.apache.storm</groupId> <artifactId>storm-core< ...
- 【a603】加工生产调度
Time Limit: 1 second Memory Limit: 32 MB [问题描述] 某工厂收到了n个产品的订单,这n个产品分别在A.B两个车间加工,并且必须先在A车间加工后才可以到B车间加 ...
- Linode跨节点迁移:从Tokyo到Fremont
背景 上一篇博客交代了如何在 Linode 上搭建邮件服务器,并配置好各种协议.记录来投入实际使用. 由于实践过程中,曾经尝试使用明文协议与服务器交流数据,可能泄露了账号.密码信息,造成之后被攻击发送 ...
- LR杂记 - Linux的系统监控工具vmstat详细说明
一.前言 非常显然从名字中我们就能够知道vmstat是一个查看虚拟内存(Virtual Memory)使用状况的工具,可是如何通过vmstat来发现系统中的瓶颈呢?在回答这个问题前,还是让我们回想一下 ...
- vue: 关于多路由公用模板,导致组件内数组缓存问题
当多个路由复用同一个模板,此时在这几个路由间切换,模板并不会重新挂载.针对这个情况,我们需要在当前逻辑内对路由做监听,在发生变化时更新对应属性,已满足需求. 但是,在实现的过程中会遇到如下情况: 如图 ...
- yii联查
$count = Acticle::find()->select("acticle_type.act_type,acticle.act_id,acticle.act_title,act ...
- 网络故障模拟,cpu高压以及docker中的实现
利用tc进行丢包 通过网络丢包来模拟网络故障,是测试中一个重要的测试项目.这对服务来说可以测试其在网络故障时的异常处理的能力,对于服务的可靠性是一个相当严苛的测试. 网卡名为$netcard,丢包率为 ...
- 编程算法 - 旋转矩阵 代码(C)
旋转矩阵 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 输出旋转矩阵, 使矩阵是按对角线螺旋上升, 在输出规则确定以后, 就能够推断, 上升规律是, ...
- python 教程 第二十一章、 扩展Python
第二十一章. 扩展Python /* D:\Python27\Lib\Extest-1.0\Extest2.c */ #include <stdio.h> #include <std ...