生活随笔
收集整理的這篇文章主要介紹了
基于Delphi API写的UDP通讯类
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
轉(zhuǎn)載地址:http://www.codefans.net/articles/159.shtml
基于Delphi API寫的UDP通訊類,可以廣播和單播,類作者:王彥鵬。這個類是作者2007年的時候?qū)懙?#xff0c;代碼里基本沒什么注釋,有需要的朋友自己摸索下,懂Delphi的應(yīng)該可以看懂。
unit TUdp_Class;
interface
usesClasses,Windows,WinSock;
typeTRecv= procedure (RIP:string;buf:pchar;Bufsize:integer) of object;TRecvExpand= procedure (RIP:string;Port:integer;buf:pchar;Bufsize:integer) of object;TUdp = class(TThread)privateWSocket:TSocket;FActive:Boolean;FPort,FSendPort:integer;Addr: TSockAddr;FSockAddrIn : TSockAddrIn;FOnRecv:TRecv;FOnRecvExpand:TRecvExpand;Rtl:TRTLCriticalSection;procedure SetPort(Value:integer);procedure SetOnRecv(value:TRecv);procedure SetOnRecvExpand(value:TRecvExpand);function GetCurPort:integer;{ Private declarations }protectedprocedure Execute; override;public constructor Create;destructor Destroy; override;function SendBuf(Host:string;Buf:pchar;BufSize:integer;Broadcast:boolean=false):integer;Function GetLocalIP():string;publishedproperty Port:integer read FPort write SetPort default 0;property SendPort:integer read FSendPort write FSendPort default 0;property OnRecv:TRecv read FOnRecv write SetOnRecv;property OnRecvExpand:TRecvExpand read FOnRecvExpand write SetOnRecvExpand;property CurPort:Integer read GetCurPort;end;
implementation
uses SysUtils;
{ TUdp }
constructor TUdp.Create();
var wsadata: Twsadata;
beginInitializeCriticalSection(rtl);if wsastartup($2, wsadata) <> 0 thenbeginRaise Exception.Create(SysErrorMessage(GetLastError));endelseWSocket:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);if WSocket= INVALID_SOCKET thenRaise Exception.Create(SysErrorMessage(GetLastError))elseinherited create(true);
end;
destructor TUdp.Destroy;
beginclosesocket(WSocket);wsacleanup();DeleteCriticalSection(Rtl);inherited;
end;
procedure TUdp.Execute;
varbuf: pchar;Len: integer;FDS:TFDSet;TimeOut:TimeVal;
beginbuf := AllocMem(10240);timeout.tv_sec := 0;timeout.tv_usec := 10;FSockAddrIn.SIn_Port := htons(FPort);while not Terminated dobeginEnterCriticalSection(rtl);fillchar(Fds,sizeof(Fds),0);FD_SET(WSocket ,fds);len:=select(0,@fds,nil,nil,@TimeOut);if len>0 thenbeginlen:=sizeof(FSockAddrIn);fillchar(buf[0],10240,0);len := recvfrom(WSocket, buf[0], 10240, 0,FSockAddrIn,len);if (len<>0) and (len<>-1) thenbeginif Assigned(fonRecv) thenFOnRecv(inet_ntoa(FSockAddrIn.sin_addr) ,buf,len);if Assigned(fOnRecvExpand) thenFOnRecvExpand(inet_ntoa(FSockAddrIn.sin_addr),htons(FSockAddrIn.sin_port),buf,len);end;end;LeaveCriticalSection(rtl);sleep(10);end;freemem(buf);closesocket(WSocket);
end;function TUdp.GetCurPort: integer;
beginResult:=htonl(FSockAddrIn.SIn_Port);
end;function TUdp.GetLocalIP(): string;
varHostEnt: PHostEnt;Ip: string;addr: pchar;Buffer: array [0..63] of char;GInitData: TWSADATA;
beginResult := '';tryWSAStartup(2, GInitData);GetHostName(Buffer, SizeOf(Buffer));HostEnt := GetHostByName(buffer);if HostEnt = nil then Exit;addr := HostEnt^.h_addr_list^;ip := Format('%d.%d.%d.%d', [byte(addr [0]),byte (addr [1]), byte (addr [2]), byte (addr [3])]);Result :=Ip;finallyWSACleanup;end;
end;function TUdp.SendBuf(Host: string; Buf:pchar; BufSize: integer;Broadcast:boolean=false ): integer;
var optval:integer;
beginif Broadcast thenbeginoptval:= 1;if setsockopt(WSocket,SOL_SOCKET,SO_BROADCAST,pchar(@optval),sizeof(optval)) = SOCKET_ERROR thenRaise Exception.Create(SysErrorMessage(GetLastError))elsebeginFSockAddrIn.SIn_Family := AF_INET;FSockAddrIn.SIn_Port := htons(FSendPort);FSockAddrIn.SIn_Addr.S_addr := INADDR_BROADCAST;result:=sendto(WSocket,buf[0],BufSize,0,FSockAddrIn,sizeof(FSockAddrIn));end;endelsebeginFSockAddrIn.SIn_Family := AF_INET;FSockAddrIn.SIn_Port := htons(FSendPort);FSockAddrIn.SIn_Addr.S_addr :=inet_addr(pchar(host));result:=sendto(WSocket,buf[0],BufSize,0,FSockAddrIn,sizeof(FSockAddrIn));end;
end;procedure TUdp.SetOnRecv(value: TRecv);
beginif @FOnRecv = @value thenexit;FOnRecv:=value;Addr.sin_family := AF_INET;addr.sin_addr.S_addr := INADDR_ANY;addr.sin_port := htons(FPort);if Bind(WSocket, addr, sizeof(addr)) <> 0 thenRaise Exception.Create(SysErrorMessage(GetLastError));Resume;
end;procedure TUdp.SetOnRecvExpand(value:TRecvExpand);
beginif @FOnRecvExpand = @value thenexit;FOnRecvExpand:=value;Addr.sin_family := AF_INET;addr.sin_addr.S_addr := INADDR_ANY;addr.sin_port := htons(FPort);if Bind(WSocket, addr, sizeof(addr)) <> 0 thenRaise Exception.Create(SysErrorMessage(GetLastError));Resume;
end;procedure TUdp.SetPort(Value: integer);
beginif FPort =Value thenexit;if FActive thenSuspend;FPort:=Value;
end;
end.
總結(jié)
以上是生活随笔為你收集整理的基于Delphi API写的UDP通讯类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。