delphi indy的UDP传输的演示源码
delphi中udp数据接收端实现

int erfac eus esWi ndows, Mes sages, Sys Utils, Var iants, Cla sses, Grap hics, Cont rols, Form s, Di alogs, Std Ctrls,Wins ock;typeTFor m1 =class(TFor m) But ton2: TBut ton; //开始接收数据 List Box1: TLis tBox; //将接收到的数据显示到列表中 Edit1: TE dit; //显示接收了多少次数据p roced ure B utton2Clic k(Sen der:TObje ct);priva te { P rivat e dec larat ions}pub lic {Publi c dec larat ions}end;pr ocedu re Ch eckRc(szEr r : P Char);va rFor m1: T Form1;con stDEFAU LT_PO RT =5150;//接收端口号DEF AULT_COUNT = 20; //接收20次D EFAUL T_BUF FER_L ENGTH = 4096; //接收数据的最大缓冲区大小v arnPort : In teger = DE FAULT_PORT;dwC ount: DWO RD =DEFAU LT_CO UNT;dwLen gth : DWOR D = D EFAUL T_BUF FER_L ENGTH ;sz Inter face: arr ay[0..31]of ch ar;wsd : WSAD ata;//保存初始化信息soRec v : T SOCKE T; //接收数据的socke tpsz Recv: PCha r; //接收数据的缓冲区指针nR et :integ er;i : in teger;dwS ender Size: Int eger;siSe nder,local : SO CKADD R_IN;nErr or :Integ er;imple menta tionpro cedur e Che ckRc(szErr : PC har);begi nMes sageB ox(0,szErr,'Err or',M B_OK);end;pr ocedu re TF orm1.Butto n2Cli ck(Se nder: TObj ect);var i:integ er;n LastE rror: Int eger;nNum OfRec v : I ntege r;be gin nNum OfRec v :=0;//初始化so cket nEr ror := WSA Start up(Ma keWor d(2,2),wsd);if Bool ean(n Error) the n Mes sageB ox(0,'WSAS tartu p','E rror',MB_O K);//建立so cketsoRec v :=socke t(AF_INET,SOCK_DGRAM,0);if so Recv= SOC KET_E RRORthenbegin Chec kRc('socke t');end;//设置端口与地址lo cal.s in_fa mily:= AF_INET;loc al.si n_por t :=htons(5150);lo cal.s in_ad dr.S_addr:= in et_ad dr('127.0.0.1');//将soc ket绑定地址nE rror:= bi nd(so Recv,local,size of(lo cal));ifnErro r = S OCKET_ERRO R the n Che ckRc('bind');//分配内存pszR ecv := All ocMem(4096);f or i:= 0to dw Count -1 d obeg in dw Sende rSize := S izeOf(siSe nder); //接收发送过来的数据,并保存到缓冲区中 nRet := r ecvFr om(so Recv,pszRe cv[0],4096,0,si Sende r,dwS ender Size); ifnRet= SOC KET_E RRORthenb egin Chec kRc('recvF rom'); br eak;e nd el se if nRet = 0then elsebegin psz Recv[nRet] := #0;//添加到列表中,仅用于显示self.ListB ox1.I tems.Add(p szRec v); en d; Inc(nNum OfRec v); se lf.Ed it1.T ext := Int ToStr(nNum OfRec v); end;//end of f or//关闭 so cketclose socke t(soR ecv);//释放分配的内存Free Mem(p szRec v);//清理wi nsock etWS AClea nup();end;en d.。
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聊天程序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传输的演示源码

/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发送数据的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作为一种简单易学、功能强大的编程语言,也在网络通信领域扮演着重要的角色。
本文将介绍如何使用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通信的例子

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 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控件: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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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.。