delphi indy的UDP传输的演示源码

合集下载

delphi中udp数据接收端实现

delphi中udp数据接收端实现

in‎t erfa‎c eu‎s esW‎i ndow‎s, Me‎s sage‎s, Sy‎s Util‎s, Va‎r iant‎s, Cl‎a sses‎, Gra‎p hics‎, Con‎t rols‎, For‎m s, D‎i alog‎s, St‎d Ctrl‎s,Win‎s ock;‎typ‎eTFo‎r m1 =‎clas‎s(TFo‎r m)‎ Bu‎t ton2‎: TBu‎t ton;‎ /‎/开始接收‎数据‎ Lis‎t Box1‎: TLi‎s tBox‎; //将‎接收到的数‎据显示到列‎表中‎ Edi‎t1: T‎E dit;‎‎ //‎显示接收了‎多少次数据‎‎p roce‎d ure ‎B utto‎n2Cli‎c k(Se‎n der:‎TObj‎e ct);‎priv‎a te‎ { ‎P riva‎t e de‎c lara‎t ions‎}pu‎b lic‎ {‎Publ‎i c de‎c lara‎t ions‎}en‎d;p‎r oced‎u re C‎h eckR‎c(szE‎r r : ‎P Char‎);v‎a rFo‎r m1: ‎T Form‎1;co‎n st‎‎DEFA‎U LT_P‎O RT =‎5150‎;‎//接收端‎口号DE‎F AULT‎_COUN‎T = 2‎0; ‎ //接‎收20次‎D EFAU‎L T_BU‎F FER_‎L ENGT‎H = 4‎096; ‎//接收数‎据的最大缓‎冲区大小‎v ar‎‎nPor‎t : I‎n tege‎r = D‎E FAUL‎T_POR‎T;dw‎C ount‎: DW‎O RD =‎DEFA‎U LT_C‎O UNT;‎dwLe‎n gth ‎: DWO‎R D = ‎D EFAU‎L T_BU‎F FER_‎L ENGT‎H ;s‎z Inte‎r face‎: ar‎r ay[0‎..31]‎of c‎h ar;‎wsd ‎: WSA‎D ata;‎//保存‎初始化信息‎soRe‎c v : ‎T SOCK‎E T; /‎/接收数据‎的sock‎e tps‎z Recv‎: PCh‎a r; ‎//接收‎数据的缓冲‎区指针n‎R et :‎inte‎g er;‎i : i‎n tege‎r;dw‎S ende‎r Size‎: In‎t eger‎;siS‎e nder‎,loca‎l : S‎O CKAD‎D R_IN‎;nEr‎r or :‎Inte‎g er;‎impl‎e ment‎a tion‎pr‎o cedu‎r e Ch‎e ckRc‎(szEr‎r : P‎C har)‎;beg‎i nMe‎s sage‎B ox(0‎,szEr‎r,'Er‎r or',‎M B_OK‎);en‎d;p‎r oced‎u re T‎F orm1‎.Butt‎o n2Cl‎i ck(S‎e nder‎: TOb‎j ect)‎;var‎‎ i:‎inte‎g er;‎n Last‎E rror‎: In‎t eger‎;nNu‎m OfRe‎c v : ‎I nteg‎e r;b‎e gin‎‎ nNu‎m OfRe‎c v :=‎0;/‎/初始化s‎o cket‎‎ nE‎r ror ‎:= WS‎A Star‎t up(M‎a keWo‎r d(2,‎2),ws‎d);i‎f Boo‎l ean(‎n Erro‎r) th‎e n‎ Me‎s sage‎B ox(0‎,'WSA‎S tart‎u p','‎E rror‎',MB_‎O K);‎//建立s‎o cket‎soRe‎c v :=‎sock‎e t(AF‎_INET‎,SOCK‎_DGRA‎M,0);‎if s‎o Recv‎= SO‎C KET_‎E RROR‎then‎begi‎n‎ Che‎c kRc(‎'sock‎e t');‎end;‎/‎/设置端口‎与地址l‎o cal.‎s in_f‎a mily‎:= A‎F_INE‎T;lo‎c al.s‎i n_po‎r t :=‎hton‎s(515‎0);l‎o cal.‎s in_a‎d dr.S‎_addr‎:= i‎n et_a‎d dr('‎127.0‎.0.1'‎);‎//将so‎c ket绑‎定地址n‎E rror‎:= b‎i nd(s‎o Recv‎,loca‎l,siz‎e of(l‎o cal)‎);if‎nErr‎o r = ‎S OCKE‎T_ERR‎O R th‎e n‎ Ch‎e ckRc‎('bin‎d');‎//分配内‎存psz‎R ecv ‎:= Al‎l ocMe‎m(409‎6);‎f or i‎:= 0‎to d‎w Coun‎t -1 ‎d obe‎g in‎ d‎w Send‎e rSiz‎e := ‎S izeO‎f(siS‎e nder‎);‎ //接‎收发送过来‎的数据,并‎保存到缓冲‎区中‎ nRe‎t := ‎r ecvF‎r om(s‎o Recv‎,pszR‎e cv[0‎],409‎6,0,s‎i Send‎e r,dw‎S ende‎r Size‎); ‎ if‎nRet‎= SO‎C KET_‎E RROR‎then‎‎b egin‎‎‎ Che‎c kRc(‎'recv‎F rom'‎);‎ b‎r eak;‎‎e nd e‎l se i‎f nRe‎t = 0‎then‎‎ els‎e‎begi‎n‎‎ ps‎z Recv‎[nRet‎] := ‎#0;‎‎//添加到‎列表中,仅‎用于显示‎‎self‎.List‎B ox1.‎I tems‎.Add(‎p szRe‎c v);‎ e‎n d;‎ In‎c(nNu‎m OfRe‎c v);‎ s‎e lf.E‎d it1.‎T ext ‎:= In‎t ToSt‎r(nNu‎m OfRe‎c v); ‎end;‎//en‎d of ‎f or/‎/关闭 s‎o cket‎clos‎e sock‎e t(so‎R ecv)‎;//释‎放分配的内‎存Fre‎e Mem(‎p szRe‎c v);‎//清理w‎i nsoc‎k etW‎S ACle‎a nup(‎);en‎d;e‎n d.‎。

Delphi的Indy10全接触之UDP篇

Delphi的Indy10全接触之UDP篇

Delphi2009的Indy全接触之UDP篇首先新建服务端。

如下图所示建立工程:代码如下:unitServerUnit;interfaceusesWindows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,IdBaseComponent, IdComponent,IdUDPBase,IdUDPServer,StdCtrls,IdSocketHandle,IdGlobal;typeTServerForm=class(TForm)Label1:TLabel;Edit1:TEdit;Label2:TLabel;Edit2:TEdit;Label3:TLabel;Edit3:TEdit;IdUDPServer1:TIdUDPServer;procedureIdUDPServer1UDPRead(AThread:TIdUDPListenerThread;AData:TBytes;ABinding:TIdSocketHandle);procedureFormCreate(Sender:TObject);private{Privatedeclarations}public{Publicdeclarations}end;varServerForm:TServerForm;implementation{$R*.dfm}//窗体创建部分procedureTServerForm.FormCreate(Sender:TObject);beginIdUDPServer1.DefaultPort:=3030;IdUDPServer1.Active:=True;Edit1.ReadOnly:=True;Edit2.ReadOnly:=True;Edit3.ReadOnly:=True;end;//数据接收部分procedureTServerForm.IdUDPServer1UDPRead(AThread:TIdUDPListenerThread;AData:TBytes;ABinding:TIdSocketHandle);beginEdit1.Text:=ABinding.PeerIP;Edit2.Text:=IntToStr(ABinding.PeERPort);Edit3.Text:=BytesToString(AData);IdUDPServer1.Send(ABinding.PeerIP,ABinding.PeerPort,TimeToStr(Time)+'=>Serverreceivedthemessage! ');end;end.然后新建客户端如下图所示:注意:为了让客户端能实时监控服务端发回来的确定消息,使用了TTimer控件,Interval设置为250毫秒。

用Delphi编写局域网中的UDP聊天程序

用Delphi编写局域网中的UDP聊天程序

用Delphi编写局域网中的UDP聊天程序Internet盛行的今天,网上聊天已成为一种时尚。

同时,各单位已建成了自己的局域网;能否在局域网上实现聊天呢?可以,网上到处都有这种工具。

当然,我们可以拥有自己版权的聊天工具。

User Datagram Protocol (UDP)协议,是一种无连接协议。

在Delphi中利用这种协议,可以轻松的编写出聊天程序,以下的程序,在Delphi 5+Pwin98中通过。

打开Delphi,新建Application放置以下几个控件:Panel1、Panel2,其属性如下:然后,放置以下控件:Edit1ListBox1Memo1Button1Button2BitBtn1Nmudp1其主要控件的属性如下:各主要控件的功能如下:现在的界面如下:源程序如下:unit main;interfaceusesWindows,messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,Buttons,ExtCtrls,NMUDP,Menus,ComCtrls,Win Sock; file://增加WinSocktypeTForm1 = class(TForm)NMUDP1: TNMUDP;Panel1: TPanel;Panel2: TPanel;Label1: TLabel;Edit1: TEdit;BitBtn1: TBitBtn;Memo1: TMemo;Panel3: TPanel;Panel4: TPanel;ListBox1: TListBox;Button1: TButton;Button2: TButton;procedure FormShow(Sender: TObject);procedure BitBtn1Click(Sender: TObject);procedure NMUDP1DataReceived(Sender: TComponent; NumberBytes: Integer;FromIP: String; Port: Integer);procedure Edit1KeyPress(Sender: TObject; var Key: Char);procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;ComputerName: array[0..127] of Char;implementation{$R *.DFM}procedure TForm1.FormShow(Sender: TObject);varsz: dword;beginsz := SizeOf(Computername);GetComputerName(ComputerNamesz);//得到本机的标识ListBox1.Items.Clear;ListBox1.Items.Add(’大家’);//在网友清单中,增加”大家”和ListBox1.Items.Add(ComputerName);//本机名称ListBox1.ItemIndex:=0;end;procedure TForm1.BitBtn1Click(Sender: TObject);varMyStream: TMemoryStream;TmpStr: String;i:integer;Beginif Edit1.Text<>’’ then file://如果所说的内容不为空则发送。

delphi indy的UDP传输的演示源码

delphi indy的UDP传输的演示源码

/t810509用Delphi编写点对点传文件程序delphi indy的UDP传输的演示源码2009-02-27 17:05客户端:varcmd: string;ASize, TotalSize: Int64;AFileStream: TFileStream;beginIdTCPClient1.Host := Edit1.Text; //连接主机IdTCPClient1.Port := StrToIntDef(Edit2.Text, 9925); //端口IdTCPClient1.Connect; //连接tryIdTCPClient1.WriteLn('BEGIN'); //提示服务器开始接收cmd := IdTCPClient1.ReadLn;//以“|”符号分离文件名SaveDialog1.FileName := Copy(cmd, Pos('|', cmd) + 1, Length(cmd));if not SaveDialog1.Execute thenbeginIdTCPClient1.WriteLn('CANCEL'); //告诉服务器取消IdTCPClient1.Disconnect; //断开连接exit;end;TotalSize := StrToInt(Copy(cmd, 0, Pos('|', cmd) - 1)); //分离文件大小//建立文件流准备接收AFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate);try //循环开始接受repeatIdTCPClient1.WriteLn(IntToStr(AFileStream.Size));//发送当前传输的位置ASize := Min(TotalSize - AFileStream.Size, IdTCPClient1.RecvBufferSize);//选择剩余大小和缓冲区大小小的一个作为传输的大小IdTCPClient1.ReadStream(AFileStream, ASize); //接收流StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, TotalSize]);Application.ProcessMessages;until AFileStream.Size = TotalSize; //大小一致了表示结束finallyAFileStream.Free; //释放文件流end;IdTCPClient1.WriteLn('END'); //提示服务器传输完成StatusBar1.SimpleText := '传输完成...';exceptStatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';end;IdTCPClient1.Disconne--------------------------------------------------------------------------------服务器:procedure Tfrm_Server.IdTCPServer1Execute(AThread: TIdPeerThread);varcmd: string; //接收到客户端的字符串信息ASize: Integer; //需要传输的流大小beginwith AThread.Connection do //已经连街上的一个进程begincmd := UpperCase(ReadLn); //客户端发送的命令字符串if cmd = 'BEGIN' then //开始传输begin//告诉远程传输文件的大小和文件名WriteLn(Format('%d|%s', [AFileStream.Size, ExtractFileName(Edit1.Text)])); StatusBar1.SimpleText := '准备传输...';Exit;end;if cmd = 'END' thenbegin //传输完成Button3.Click;StatusBar1.SimpleText := '传输完成...';Exit;end;if cmd = 'CANCEL' thenbegin //传输取消StatusBar1.SimpleText := '传输取消...';//保持传输状态Exit;end;//按照指定位置传输文件AFileStream.Seek(StrToInT(cmd), soFromBeginning); //转到文件流传输的位置ASize := Min(AFileStream.Size - AFileStream.Position, RecvBufferSize);//计算需要发送的大小,Min()函数在Math单元OpenWriteBuffer; //准备发送缓冲WriteStream(AFileStream, false, false, ASize);//注意这个函数的参数。

udp 发送 例程

udp 发送 例程

udp 发送例程
以下是一个简单的UDP发送数据的Python例程:
```python
import socket
# 目标服务器的IP和端口
server_ip = '127.0.0.1'
server_port = 12345
# 创建一个UDP套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try:
message = '这是要发送的消息'
print(f"正在向{server_ip}:{server_port} 发送消息:{message}")
# 发送消息
sock.sendto(message.encode(), (server_ip, server_port)) finally:
print('关闭套接字')
sock.close()
```
这段代码首先导入了`socket`模块,然后定义了目标服务器的IP 地址和端口号。

接着,创建了一个UDP套接字,并向服务器发送了一条消息。

最后,关闭了套接字。

注意,在实际使用中,你可能需要处理各种可能的错误,例如网络连接问题或服务器不可达等。

这只是一个基本的UDP发送数据的例程,具体实现可能会根据你的实际需求有所不同。

Python编写高性能TCP UDP网络通信程序

Python编写高性能TCP UDP网络通信程序

Python编写高性能TCP UDP网络通信程序随着互联网的快速发展,网络通信在现代社会中变得越来越重要。

而Python作为一种简单易学、功能强大的编程语言,也在网络通信领域扮演着重要的角色。

本文将介绍如何使用Python编写高性能的TCP和UDP网络通信程序。

一、TCP和UDP协议简介在开始介绍Python编写网络通信程序之前,我们先来了解一下TCP和UDP协议。

TCP(Transmission Control Protocol)是一种面向连接的协议,通过建立可靠的连接来传输数据,保证数据的可靠性和顺序性。

TCP适用于对数据可靠性要求较高的场景,如文件传输、网页浏览等。

UDP(User Datagram Protocol)是一种无连接的协议,数据包的发送和接收不需要建立连接,也不保证数据的可靠性和顺序性。

UDP适用于对实时性要求较高、数据传输量较大或不需要保证可靠性的场景,如音频视频传输、游戏等。

二、Python网络编程库在Python中,有许多第三方库可以帮助我们实现高性能的网络通信程序。

其中,最常用的库包括socket、asyncio和twisted等。

1. Socket库Socket库是Python标准库中提供的用于网络编程的核心模块,它提供了一些基本的函数和类,用于创建、连接、发送和接收网络数据。

下面是使用Socket库创建TCP和UDP服务器的示例代码:```python# TCP Serverimport socketserver_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 创建TCP服务器server_socket.bind(('localhost', 8888)) # 绑定地址和端口server_socket.listen(5) # 监听端口,接受最大连接数为5while True:client_socket, address = server_socket.accept() # 建立连接data = client_socket.recv(1024) # 接收数据print('Received:', data.decode())client_socket.send('Hello, client!'.encode()) # 发送数据client_socket.close() # 关闭连接# UDP Serverimport socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建UDP服务器server_socket.bind(('localhost', 9999)) # 绑定地址和端口while True:data, address = server_socket.recvfrom(1024) # 接收数据print('Received:', data.decode())server_socket.sendto('Hello, client!'.encode(), address) # 发送数据```2. asyncio库asyncio库是Python 3.4版本引入的标准库,用于实现异步IO编程。

delphi一个用socket封装UDPTCP通信的例子

delphi一个用socket封装UDPTCP通信的例子

unit UnitTCPUDP;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls,WinSock, ExtCtrls, ComCtrls,inif iles,StrUtils;constWM_SOCK = WM_USER + 82; {自定义windows消息}//在tcp 服务器方式下,WM_SOCK为监听消息// WM_SOCK+1到 WM_SOCK+MAX_ACCEPT 为与连接客户端进行通讯时的消息MAX_ACCEPT=100;FD_SET= MAX_ACCEPT;typeTFormTCPUDP = class(TForm)BtnSend: TButton;MemoReceive: TMemo;EditSend: TEdit;Label2: TLabel;Label3: TLabel;Bevel2: TBevel;STOpCode: TStaticText;STIndex: TStatic Text;STCommand: TStatic Text;GroupBox1: TGroupBox;GroupBox2: TGroupBox;GroupBox3: TGroupBox;RBTCP: TRadioButton;RBUDP: TRadioButton;Panel1: TPanel;RBClient: TRadioButton;RBServer: TRadioButton;GroupBox4: TGroupBox;BtnConnect: TButton;BtnClose: TButton;Bevel1: TBevel;StatusBar1: TStatusBar;PanelDest: TPanel;Label4: TLabel;EditRemoteHost: TEdit;Label5: TLabel;EditRemotePort: TEdit;Label6: TLabel;CmbSendTo: TComboBox;Label7: TLabel;PanelLocal: TPanel;ChkBind: TCheckBox;EditHostPort: TEdit;Label1: TLabel;procedure BtnSendClick(Sender: TObject);procedure BtnConnectClick(Sender: TObject);procedure RBTCPClick(Sender: TObject);procedure RBUDPClick(Sender: TObject);procedure BtnCloseClick(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure RBClientClick(Sender: TObject);procedure RBServerClick(Sender: TObject);procedure ChkBindClick(Sender: TObject);procedure FormCreate(Sender: TObject);procedure EditHostPortChange(Sender: TObject);procedure EditRemoteHostChange(Sender: TObject);procedure EditRemotePortChange(Sender: TObject);procedure FormActivate(Sender: TObject);procedure CmbSendToKeyPress(Sender: TObject; var Key: Char); {消息接送}private{ Private declarations }FirstFlag:Boolean;INIPath:String;procedure R eadData(var Message: TMessage);function ReadTCPUDPIni():boolean; //读取配置信息procedure Wri t eIniStr(FileName:String;section:string;Ident:string;StringValue:string);//写系统信息 procedure Wri t eIniBool(FileName:String;section:string;Ident:string;BoolValue:Boolean);//写系统信息 protected{ Protected declarations }{ other fields and methods}procedure wndproc(var message:Tmessage);override;public{ Public declarations }end;constDATA_LENGTH =120; //数据长度typeTUDPaction = packed recordopcode:byte; //操作码index:word; //序列号Command:byte; //命令字data:array[0..(DATA_LENGTH-1)] of char; //数据end;varFormTCPUDP: TFormTCPUDP;AcceptSock:Array[0..MAX_ACCEPT] OF Tsocket;FSockAccept : Array[0..MAX_ACCEPT] OF TSockAddrIn;AcceptSockFlag: Array[0..MAX_ACCEPT] OF boolean;AcceptNum:integer=0;FSockLocal : TSockAddrIn;PackageID:integer=0; //包序号BindFlag:Boolean=true;TcpFlag:Boolean=false;ServerFlag:Boolean=false;function WinSockInital(Handle: HWnd):bool;Procedure WinSockClose();implementation{$R *.dfm}{始化SOCKET}function WinSockInital(Handle: HWnd):bool;var TempWSAData: TWSAData;i:integer;beginresult := false;{ 1 初始化SOCKET}if WSAStartup(2, TempWSAData)=1 then //2表示启用winsock2 exi t;{若是用UDP通信,则用}if TcpFlag thenAcceptSock[0]:=Socket(AF_INET,SOCK_STREAM,0)elseAcceptSock[0]:=Socket(AF_INET,SOCK_DGRAM,0);if AcceptSock[0]=SOCKET_ERROR thenexi t;if (BindFlag and not tcpflag) or (Serverflag and tcpflag) thenif bind(AcceptSock[0],FSockLocal,sizeof(FSockLocal))<>0 then beginWinSockClose();exit;end;if Tcpflag thenif Serverflag thenbeginif Listen(AcceptSock[0],1)<>0 then //等待连接队列的最大长度为1begin&nbsp;WinSockClose();exi t;end;endelseif connect(AcceptSock[0],FSockAccept[0],sizeof(FSockAccept[0]))<>0 thenbeginWinSockClose();exi t;end;{FD_READ 在读就绪的时候, 产生WM_SOCK 自定义消息号}if not TcpFlag thenWSAAsyncSelect(AcceptSock[0], Handle , WM_SOCK, FD_READ)else if Serverflag thenWSAAsyncSelect(AcceptSock[0], Handle , WM_SOCK, FD_READ or FD_ACCEPT or FD_CLOSE) elseWSAAsyncSelect(AcceptSock[0], Handle , WM_SOCK, FD_READ or FD_CLOSE);R esult:=true;end;{关闭SOCKET}Procedure WinSockClose();var i:integer;beginfor i:=1 to MAX_ACCEPT DOif AcceptSockFlag[i] thenbeginCloseSocket(AcceptSock[i]);AcceptSockFlag[i]:=false;end;CloseSocket(AcceptSock[0]); {closesocket函数用来关闭一个描述符为AcceptSock[0]套接字}WSACleanup;end;function TFormTCPUDP.ReadTCPUDPIni():boolean;var ti:TiniFile;beginti:=TIniFile.Create(INIPath+'TCPUDP.ini');EditHostPort.text:=ti.ReadString('Setting','LocalPort','');ChkBind.Checked:=ti.ReadBool('Setting','BindStatus',false);EditR emotePort.text:=ti.ReadString('Setting','RemotePort','');EditR emoteHost.text:=ti.ReadString('Setting','R emoteHost','');RBTCP.Checked:=ti.ReadBool('Setting','TCPStatus',false);RBUDP.Checked:=not RBTCP.Checked;RBServer.Checked:=ti.R eadBool('Setting','ServerStatus',false);RBClient.Checked:=not RBServer.Checked;end;procedure TFormTCPUDP.WriteIniStr(FileName:String;Section:string;Ident:string;StringValue:string); var ti:TiniFile;beginti:=TIniFile.Create(FileName);ti.writestring(section,Ident,StringValue);ti.Free;end;procedure TFormTCPUDP.WriteIniBool(FileName:String;Section:string;Ident:string;BoolValue:Boolean); var ti:TiniFile;beginti:=TIniFile.Create(FileName);ti.writebool(section,Ident,BoolValue);ti.Free;end;procedure TFormTCPUDP.BtnSendClick(Sender: TObject);var SEND_PACKAGE : TUDPaction; //数据发送i:integer;s:String;beginFillchar(SEND_PACKAGE.data,Data_Length,chr(0));SEND_PACKAGE.data[0]:='1';SEND_PACKAGE.data[1]:='2';SEND_PACKAGE.data[2]:='3';SEND_PACKAGE.opcode:=2;SEND_PACKAGE.index:=PackageID;SEND_mand:=3;s:=editsend.Text;for i:=0 to length(EditSend.Text)-1 doSEND_PACKAGE.data[i]:=s[i+1];PackageID:=PackageID+1;if not (Tcpflag and Serverflag) thensendto(AcceptSock[0], SEND_PACKAGE,sizeof(SEND_PACKAGE), 0, FSockAccept[0], sizeof(FSockAcce pt[0]))else if AcceptNum=0 thenApplication.MessageBox('没有一个客户端和您建立连接','信息提示',MB_OK)elsebegini:=pos(' ',CmbSendto.Text);if i>0 thenbegini:=strtoint(MidStr(CmbSendTo.Text,8,i-8));sendto(AcceptSock[i], SEND_PACKAGE,sizeof(SEND_PACKAGE), 0, FSockAccept[i], sizeof(FSockAcce pt[i]));endelseApplication.MessageBox('您没有选择发送方','错误提示',MB_OK);end;// sendto(AcceptSock[0], NbtstatPacket,50, 0, FSockAccept[0], sizeof(FSockAccept[0]));end;procedure TFormTCPUDP.BtnConnectClick(Sender: TObject);var s:String;i:integer;begins:='正在建立连接....';StatusBar1.Panels[0].Text:=s;Application.ProcessMessages;FSockLocal.sin_family:=AF_INET;FSockLocal.sin_port:=htons(strtoint(Edi t Hostport.Text));FSockAccept[0].sin_family:=AF_INET;FSockAccept[0].sin_port:=htons(strtoint(EditRemoteport.Text));FSockAccept[0].SIn_Addr.S_addr := inet_addr(PChar(EditR emoteHost.Text));//inet_addr(pchar(IP)); if WinSockInital(FormTCPUDP.Handle) thenbeginBtnConnect.Enabled:=false;BtnClose.Enabled:=true;BtnSend.Enabled:=true;s:='连接成功!';if ChkBind.Checked thens:=s+', ---绑定端口';if RBTcp.Checked thenbegins:=s+',---TCP方式';if RBServer.Checked thens:=s+',---服务端'elses:=s+',---客户端';endelses:=s+',---UDP方式';if tcpflag and Serverflag thenbeginAcceptNum:=0;CmbSendto.Clear;StatusBar1.Panels[2].Text:='共有:'+inttostr(AcceptNum)+'个连接';end;endelsebeginfor i:=0 to StatusBar1.Panels.count-1 doStatusBar1.Panels[i].Text:='';s:='创建套接字失败!!';end;StatusBar1.Panels[0].Text:=s;end;procedure TFormTCPUDP.wndproc(var Message: TMessage);beginif (Message.Msg>=WM_SOCK) and (Message.Msg<=WM_SOCK+MAX_ACCEPT) thenReadData(Message)elseinherited wndproc(message);end;procedure TFormTCPUDP.ReadData(var Message: TMessage);varReceive_PACKAGE : TUDPaction; //数据发送flen,len,i,index: integer;Event: word;beginIndex:=(Message.Msg-WM_SOCK);flen:=sizeof(FSockAccept[Index]);Event := WSAGetSelectEvent(Message.LParam);if Event = FD_READ thenbeginlen := recvfrom(AcceptSock[Index], Receive_PACKAGE, sizeof(R eceive_PACKAGE), 0, FSockAccept[In dex], Flen);if len> 0 thenbeginStatusBar1.Panels[0].Text:='收到来自ip地址:'+inet_ntoa(FSockAccept[Index].sin_addr)+' 端口:'+inttostr(ntohs(FSockAccept[Index].sin_port))+'的数据';StOpCode.Caption:= format('%.2d',[Receive_PACKAGE.opCode]);StIndex.Caption:= format('%d',[Receive_PACKAGE.Index]);StCommand.Caption:= format('%.2d',[R eceive_mand]);MemoR eceive.Lines.Add(StrPas(Receive_PACKAGE.data))end;endelse if Event=FD_ACCEPT thenbeginfor i:=1 to MAX_ACCEPT DOif not AcceptSockFlag[i] thenbeginflen:=Sizeof(FSockAccept[i]);AcceptSock[i]:=accept(AcceptSock[0],@FSockAccept[i],@flen);WSAAsyncSelect(AcceptSock[i], Handle , WM_SOCK+i, FD_READ or FD_CLOSE);AcceptSockFlag[i]:=true;AcceptNum:=AcceptNum+1;CmbSendto.I tems.Add('套接口:'+inttostr(i)+' 地址:'+inet_ntoa(FSockAccept[i].sin_addr)+' 端口:'+inttostr(ntohs(FSockAccept[i].sin_port)));break;end;StatusBar1.Panels[2].Text:='共有:'+inttostr(AcceptNum)+'个连接';endelse if Event=FD_CLOSE thenbeginWSAAsyncSelect(AcceptSock[index], FormTCPUDP.Handle, 0, 0);if index<>0 thenbeginfor i:=0 to CmbSendto.I tems.Count-1 doif CmbSendto.I tems.Strings[i]= '套接口:'+inttostr(index)+' 地址:'+inet_ntoa(FSockAccept[index].sin_addr)+' 端口:'+inttostr(ntohs(FSockAccept[index].sin_port)) thenbeginCmbSendto.Items.Delete(i);break;end;CloseSocket(AcceptSock[index]);AcceptSockFlag[index]:=false;AcceptNum:=AcceptNum-1;StatusBar1.Panels[2].Text:='共有:'+inttostr(AcceptNum)+'个连接';end;end;end;procedure TFormTCPUDP.RBTCPClick(Sender: TObject);beginwriteiniBool(INIPath+'TCPUDP.ini','Setting','TCPStatus',true);RBServer.Enabled:=true;RBClient.Enabled:=true;if RBServer.Checked thenbeginPanelDest.Visible:=false;CmbSendto.Enabled:=true;endelsebeginPanelDest.Visible:=true;PanelLocal.Visible:=false;end;ChkBind.Enabled:=false;TcpFlag:=true;end;procedure TFormTCPUDP.RBUDPClick(Sender: TObject);beginwriteiniBool(INIPath+'TCPUDP.ini','Setting','TCPStatus',false);RBServer.Enabled:=false;RBClient.Enabled:=false;PanelDest.Visible:=true;TcpFlag:=false;ChkBind.Enabled:=true;CmbSendto.Enabled:=false;PanelLocal.Visible:=true;end;procedure TFormTCPUDP.BtnCloseClick(Sender: TObject);var i:integer;beginWinSockClose();BtnConnect.Enabled:=true;BtnClose.Enabled:=false;BtnSend.Enabled:=false;CmbSendto.Clear;for i:=0 to StatusBar1.Panels.count-1 doStatusBar1.Panels[i].Text:='';Statusbar1.Panels[0].Text:='已关闭套接字!!';end;procedure TFormTCPUDP.FormClose(Sender: TObject; var Action: TCloseAction); beginif BtnClose.Enabled then WinSockClose();end;procedure TFormTCPUDP.RBClientClick(Sender: TObject);beginwriteiniBool(INIPath+'TCPUDP.ini','Setting','ServerStatus',false);ServerFlag:=false;PanelDest.Visible:=true;CmbSendto.Enabled:=false;if Tcpflag thenPanelLocal.Visible:=falseelsePanelLocal.Visible:=true;end;procedure TFormTCPUDP.RBServerClick(Sender: TObject);beginwriteiniBool(INIPath+'TCPUDP.ini','Setting','ServerStatus',true);ServerFlag:=true;if Tcpflag thenbeginPanelDest.Visible:=false;CmbSendto.Enabled:=true;ChkBind.Enabled:=false;ChkBind.Checked:=true;endelseChkBind.Enabled:=true;PanelLocal.Visible:=true;end;procedure TFormTCPUDP.ChkBindClick(Sender: TObject);beginwriteiniBool(INIPath+'TCPUDP.ini','Setting','BindStatus',ChkBind.Checked); BindFlag:=ChkBind.Checked;end;procedure TFormTCPUDP.FormCreate(Sender: TObject);var i:integer;beginFirstFlag:=true;for i:=1 to MAX_ACCEPT doAcceptSockFlag[i]:=false;INIPath:=extractFilePath(ParamStr(0));end;procedure TFormTCPUDP.EditHostPortChange(Sender: TObject);beginwriteiniStr(INIPath+'TCPUDP.ini','Setting','LocalPort',EditHostPort.Text);end;procedure TFormTCPUDP.EditRemoteHostChange(Sender: TObject);beginwriteiniStr(INIPath+'TCPUDP.ini','Setting','RemoteHost',EditR emoteHost.Text); end;procedure TFormTCPUDP.EditRemotePortChange(Sender: TObject);beginwriteiniStr(INIPath+'TCPUDP.ini','Setting','RemotePort',EditRemotePort.Text); end;procedure TFormTCPUDP.FormActivate(Sender: TObject);beginif FirstFlag thenbeginFirstFlag:=false;ReadTCPUDPIni();end;end;procedure TFormTCPUDP.CmbSendToKeyPress(Sender: TObject; var Key: Char); beginkey:=chr(0);end;end.。

DELPHI中两个UDP控件的用法

DELPHI中两个UDP控件的用法

DELPHI中有两个UDP控件:TIdUDPServer和TIdUDPClient控件,可用于传输UDP数据;用法都很简单,主要是一些细微的特性,弄清楚了对正确使用这两种控件有很大的好处;下面分别介绍:一、TIdUDPServer:代表一个UDP的服务端,接收UDP客户端发过来的数据;在FORM上放置一个TIdUDPServer控件,命名为UDPSvr,在FormCreate 事件中编写如下代码:UDPSvr.Bindings.Add;UDPSvr.Bin dings[0].IP := ‘192.168.2.117’;UDPSvr.Bindings[0].Port := 1812;UDPSvr.Active := True;在UDPSvr控件的OnUDPRead事件中编写如下代码:varBuffer: array[0..1024] of Char;iSize: integer;sData: string;beginZeroMemory(@Buffer,sizeof(Buffer));iSize := AData.Size;if iSize > 1024 thenbeginiSize := 1024;end;AData.Seek(0,soFromBeginning);iSize := AData.Read(Buffer,iSize);。

{对接收数据的处理}end;这样就完成了一个可以接收数据的UDP应用程序;其实TIdUDPServer有发送数据的方法:Send和SendBuffer,是继承自TIdUPDBase,所以只要利用TIdUDPServer控件就可完成数据的收发,在FORM 上添加一个Tbutton控件,在Click事件中添加如下代码;varBuffer: array[0..1024] of Char;sText: string;iLen: integer;beginsText := ‘12345678’ZeroMemory(@Buffer,sizeof(Buffer));StrPCopy(Buffer,sText);iLen := Length(sText);UDPSvr.SendBuffer(‘192.168.2.117’,1814,Buffer,iLen);end;这样就可以向另一UDP应用程序发送数据;一个TIdUDPServer控件可以打开多个端口,如下的代码打开了两个端口:UDPSvr.Bindings.Add;UDPSvr.Bindings[0].IP := GetLocalIP;UDPSvr.Bindings[0].Port := 1812;UDPSvr.Bindings.Add;UDPSvr.Bindings[1].IP := GetLocalIP;UDPSvr.Bindings[1].Port := 1813;UDPSvr.Active := True;当打开多个端口时,发送数据是从哪个端口发送出去呢?根据测试结果是:最近收到数据的那个端口;如果还没有收到过数据,则为Bindings[0].Port;在接收数据的事件中,有一个TidSocketHandle类型的参数:Abinding;这个参数有两对属性:IP 、Port:代表本地IP地址和端口;PeerIP、PeerPort:代表远端IP地址和端口;其中PeerIP、PeerPort在交复发送数据的UDP应用中是很有用的,因为UDP服务端可以向PeerIP和PeerPort回应数据,而不用再去设置UDP客户端的IP地址和端口号(这种方法应用不当,会产生问题,下面会说到);二、TIdUDPClient:代表一个UDP的客户端,专门用于发送UDP数据,不能接收数据,因为没有相应的事件和方法;前面已经说过,利用TIdUDPServer 控件就可以完成UDP数据的收发,所以一直怀疑TIdUDPClient控件存在的必要性;除非有一个UDP的客户端只发送数据,而从不接收数据,这样的客户端应该很少;后来我想,可能可以用TIdUDPClient控件来分担TIdUDPServer控件的负载,在一个需要收发大量UDP数据的服务端中,TIdUDPServer控件只接收数据,另外专门用一个TIdUDPClient控件发送数据,也许可以提高应用程序的性能(没有经过验证);利用TIdUDPClient发送数据有两种方式:1、利用TIdUDPClient控件本身的Send和SendBuffer方法,这时需要设置Host和Port属性,在FORM上放置一个TIdUDPClient控件,命名为:UDPClt;分别设置Host和Port属性值为:192.168.2.117和1814;再编写如下代码:varBuffer: array[0..1024] of Char;sText: string;iLen: integer;beginsText := ‘12345678’;ZeroMemory(@Buffer,sizeof(Buffer));StrPCopy(Buffer,sText);iLen := Length(sText);UDPClt.SendBuffer(Buffer,iLen);end;2、不需要设置Host和Port属性,而直接利用从TIdUPDBase继承来的Send和SendBuffer方法,也可发送数据,代码如下所示:UDPClt.SendBuffer(‘192.168.2.117’,1814,Buffer,iLen);TIdUDPClient控件发送数据时是通过哪个端口发出去的呢?根据测试的结果:是随机的;这样就给上面说过的UDP服务端可以向PeerIP和PeerPort回应数据造成了麻烦,也就是说如果UDP服务端收到的数据是通过TIdUDPClient控件发过来的,就不能通过PeerIP和PeerPort回应回去,而应设定客户端的IP地址和端口号;在具体应用中是哪种情况,要根据测试结果而定。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/t810509用Delphi编写点对点传文件程序delphi indy的UDP传输的演示源码2009-02-27 17:05客户端:varcmd: string;ASize, TotalSize: Int64;AFileStream: TFileStream;beginIdTCPClient1.Host := Edit1.Text; //连接主机IdTCPClient1.Port := StrToIntDef(Edit2.Text, 9925); //端口IdTCPClient1.Connect; //连接tryIdTCPClient1.WriteLn('BEGIN'); //提示服务器开始接收cmd := IdTCPClient1.ReadLn;//以“|”符号分离文件名SaveDialog1.FileName := Copy(cmd, Pos('|', cmd) + 1, Length(cmd));if not SaveDialog1.Execute thenbeginIdTCPClient1.WriteLn('CANCEL'); //告诉服务器取消IdTCPClient1.Disconnect; //断开连接exit;end;TotalSize := StrToInt(Copy(cmd, 0, Pos('|', cmd) - 1)); //分离文件大小//建立文件流准备接收AFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate);try //循环开始接受repeatIdTCPClient1.WriteLn(IntToStr(AFileStream.Size));//发送当前传输的位置ASize := Min(TotalSize - AFileStream.Size, IdTCPClient1.RecvBufferSize);//选择剩余大小和缓冲区大小小的一个作为传输的大小IdTCPClient1.ReadStream(AFileStream, ASize); //接收流StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, TotalSize]);Application.ProcessMessages;until AFileStream.Size = TotalSize; //大小一致了表示结束finallyAFileStream.Free; //释放文件流end;IdTCPClient1.WriteLn('END'); //提示服务器传输完成StatusBar1.SimpleText := '传输完成...';exceptStatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';end;IdTCPClient1.Disconne--------------------------------------------------------------------------------服务器:procedure Tfrm_Server.IdTCPServer1Execute(AThread: TIdPeerThread);varcmd: string; //接收到客户端的字符串信息ASize: Integer; //需要传输的流大小beginwith AThread.Connection do //已经连街上的一个进程begincmd := UpperCase(ReadLn); //客户端发送的命令字符串if cmd = 'BEGIN' then //开始传输begin//告诉远程传输文件的大小和文件名WriteLn(Format('%d|%s', [AFileStream.Size, ExtractFileName(Edit1.Text)])); StatusBar1.SimpleText := '准备传输...';Exit;end;if cmd = 'END' thenbegin //传输完成Button3.Click;StatusBar1.SimpleText := '传输完成...';Exit;end;if cmd = 'CANCEL' thenbegin //传输取消StatusBar1.SimpleText := '传输取消...';//保持传输状态Exit;end;//按照指定位置传输文件AFileStream.Seek(StrToInT(cmd), soFromBeginning); //转到文件流传输的位置ASize := Min(AFileStream.Size - AFileStream.Position, RecvBufferSize);//计算需要发送的大小,Min()函数在Math单元OpenWriteBuffer; //准备发送缓冲WriteStream(AFileStream, false, false, ASize);//注意这个函数的参数。

CloseWriteBuffer; //结束发送缓冲StatusBar1.SimpleText := Format('当前传输位置%s/大小%d', [cmd, AFileStream.Size]);ProgressBar1.Position := ProgressBar1.Position + ASize;end;end;--------------------------------------------------------------------------------UP--------------------------------------------------------------------------------Simple UDP client demoVerified;Indy 9:D7: 25th Oct 2004 Andy Neillans}unit UDPClientMain;interfaceusesWindows, Messages, Graphics, Controls, Forms, Dialogs, IdWinsock2, stdctrls, SysUtils, Classes, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze, IdComponent, IdUDPBase, IdUDPClient, IdStack;typeTUDPMainForm = class(TForm)SourceGroupBox: TGroupBox;HostNameLabel: TLabel;HostAddressLabel: TLabel;HostName: TLabel;HostAddress: TLabel;UDPAntiFreeze: TIdAntiFreeze;PortLabel: TLabel;Port: TLabel;DestinationLabel: TLabel;DestinationAddress: TLabel;BufferSizeLabel: TLabel;BufferSize: TLabel;UDPMemo: TMemo;SendButton: TButton;UDPClient: TIdUDPClient;procedure FormCreate(Sender: TObject);procedure SendButtonClick(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varUDPMainForm: TUDPMainForm;implementationconstHOSTNAMELENGTH = 80;RECIEVETIMEOUT = 5000; // milliseconds{$R *.DFM}procedure TUDPMainForm.FormCreate(Sender: TObject);beginRandomize; // remove if you want reproducible results. HostName.Caption := UDPClient.LocalName;HostAddress.Caption := GStack.LocalAddress;Port.Caption := IntToStr(UDPClient.Port); DestinationAddress.Caption := UDPClient.Host;BufferSize.Caption := IntToStr(UDPClient.BufferSize); UDPClient.ReceiveTimeout := RECIEVETIMEOUT;end;procedure TUDPMainForm.SendButtonClick(Sender: TObject);varMessageID: Integer;ThisMessage: String;ReceivedString: String;beginMessageID := Random(MAXINT);ThisMessage := 'Message: ' + IntToStr(MessageID); UDPMemo.Lines.Add('Sending ' + ThisMessage);UDPClient.Send(ThisMessage);ReceivedString := UDPClient.ReceiveString();if ReceivedString = '' thenUDPMemo.Lines.Add('No response received from the server after ' + IntToStr(UDPClient.ReceiveTimeout) + ' millseconds.')elseUDPMemo.Lines.Add('Received: ' + ReceivedString)end;end.--------------------------------------------------------------------------------Notes:Simple UDP server demoVerified:Indy 9:D7: 25th Oct 2004 Andy Neillans}unit UDPServerMain;interfaceusesWindows, Messages, Graphics, Controls, Forms, Dialogs, IdWinsock2, stdctrls, SysUtils, Classes, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze, IdComponent, IdUDPBase, IdUDPClient, IdStack, IdUDPServer, IdSocketHandle;typeTUDPMainForm = class(TForm)SourceGroupBox: TGroupBox;HostNameLabel: TLabel;HostAddressLabel: TLabel;HostName: TLabel;HostAddress: TLabel;UDPServer: TIdUDPServer;UDPAntiFreeze: TIdAntiFreeze;PortLabel: TLabel;Port: TLabel;BufferSizeLabel: TLabel;BufferSize: TLabel;UDPMemo: TMemo;procedure FormCreate(Sender: TObject);procedure UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);private{ Private declarations }public{ Public declarations }end;varUDPMainForm: TUDPMainForm;implementationconstHOSTNAMELENGTH = 80;{$R *.DFM}procedure TUDPMainForm.FormCreate(Sender: TObject);beginHostName.Caption := UDPServer.LocalName;HostAddress.Caption := GStack.LocalAddress;Port.Caption := IntToStr(UDPServer.DefaultPort);BufferSize.Caption := IntToStr(UDPServer.BufferSize);UDPServer.Active := True;end;procedure TUDPMainForm.UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);varDataStringStream: TStringStream;s: String;beginDataStringStream := TStringStream.Create('');tryDataStringStream.CopyFrom(AData, AData.Size);UDPMemo.Lines.Add('Received "' + DataStringStream.DataString + '" from ' + ABinding.PeerIP + ' on port ' + IntToStr(ABinding.PeerPort));s := 'Replied from ' + UDPServer.LocalName + ' to "' + DataStringStream.DataString + '"'; ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));finallyDataStringStream.Free;end;end;end.。

相关文档
最新文档