日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在多线程中使用UDP

發(fā)布時間:2023/12/10 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在多线程中使用UDP 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在多線程中使用UDP

來自:painboy, 時間:2004-8-8 11:34:40, ID:2754268
type TUdpThread = class(TThread)
?private
???FData ????: PChar; ???????//數(shù)據(jù)區(qū)
???FBytes ???: Integer; ?????//數(shù)據(jù)區(qū)大小
???FFromIP ??: string; ??????//UDP的源地址
???FFromPort : Integer; ?????//UDP的源端口
?public
???constructor Create(Buffer: PChar; NumberBytes: Integer; FromIP: String; Port: Integer);
?protected
???procedure Execute; override;
end;



procedure TForm1.Button1Click(Sender: TObject);
var Buffer : array[0..1024] of char;
begin
?strcopy(buffer,pchar(Edit1.Text));
?UdpSend.ReportLevel := Status_Basic;
?UdpSend.RemotePort := 4000;
?UdpSend.RemoteHost := '127.0.0.1';
?UdpSend.Sendbuffer(buffer,256);
end;


constructor TUdpThread.Create(Buffer: PChar; NumberBytes: Integer; FromIP: String; Port: Integer);
begin
?inherited Create(True);

?FData ????:= Buffer;
?FBytes ???:= NumberBytes;
?FFromIP ??:= FromIP;
?FFromPort := Port;

?FreeOnTerminate := True;
?Resume;
end;

procedure TUdpThread.Execute;
var Buffer : PChar;
???BackTo : array[0..1] of char;
???str ???: string;
???myUDP ?: TNMUDP;
begin
?str := inttostr(GetTickCount)+' : ';
?GetMem(Buffer, FBytes+1);
?CopyMemory(Buffer, FData, FBytes);

?Randomize; ?????????????????????????????
?Sleep(Random(5000)); ???????????????????
?Form1.Memo1.Lines.Add(str+Buffer); ?
?//其實以上幾句改為你自己的處理代碼就是了 ???
?
?FillChar(BackTo, 2, f);
?myUDP := TNMUDP.Create(Nil);
?myUDP.RemoteHost ?:= FFromIP;
?myUDP.ReportLevel := Status_Basic;
?myUDP.LocalPort ??:= 4000;

?myUDP.SendBuffer(BackTo, 2); ???????????//回個響應(yīng)包給對方

?FreeMem(Buffer, FBytes+1);
?FreeMem(FData, FBytes);
end;

procedure TForm1.UdpRecvDataReceived(Sender: TComponent;
?NumberBytes: Integer; FromIP: String; Port: Integer);
var Buffer : PChar ;
begin
?GetMem(Buffer, NumberBytes);
?UdpRecv.ReadBuffer(Buffer^, NumberBytes); ???????????????//接收數(shù)據(jù)
?TUdpThread.Create(Buffer, NumberBytes, FromIP, Port); ???//將數(shù)據(jù)交給子線程處理
end;

procedure TForm1.UdpSendDataReceived(Sender: TComponent;
?NumberBytes: Integer; FromIP: String; Port: Integer);
var Buffer : PChar ;
begin
?GetMem(Buffer, NumberBytes);
?UdpSend.ReadBuffer(Buffer^, NumberBytes);
?FreeMem(Buffer, NumberBytes);
end;


來自:painboy, 時間:2004-8-8 13:56:05, ID:2754370
SORRY,看錯題了。你是說要在線程里收發(fā)數(shù)據(jù)。用API重寫了一下,D5下通過了。

type TUdpThread = class(TThread)
?private
???FSocket : TSocket;
?public
???constructor Create;
?protected
???procedure Execute; override;
???function CanRead(Socket : TSocket; Timeout: Integer): Boolean;
end;


constructor TUdpThread.Create;
begin
?inherited Create(True);
?FreeOnTerminate := True;
?Resume;
end;

function TUdpThread.CanRead(Timeout: Integer): Boolean;
var
?TimeV: TTimeVal;
?FDSet: TFDSet;
?X ???: integer;
begin
?TimeV.tv_usec := (Timeout mod 1000) * 1000;
?TimeV.tv_sec := Timeout div 1000;
?FDSet.fd_count := 1;
?FDSet.fd_array[0] := FSocket;
?X := Select(0, @FDSet, nil, nil, @TimeV);
?Result := X>0;
end;

procedure TUdpThread.Execute;
var
?wsaD ?????: WSADATA;
?sa ???????: TSockAddrIn;
?nLen,nFrom: Integer;
?UdpBuffer : array[0..1023] of Char;
begin
?WSAStartup(01, wsaD);
?FSocket := Socket(AF_INET, SOCK_DGRAM, 0);
?if (FSocket <> INVALID_SOCKET) then begin
???sa.sin_family:= AF_INET;
???sa.sin_port:= htons(4096);
???sa.sin_addr.S_addr:= inet_addr('127.0.0.1');
???nLen:= SizeOf(sa);
???bind(FSocket, sa, nLen);
???While not Terminated do
?????if CanRead(10) then begin ????????????????????????????????//檢查是否有數(shù)據(jù)可接收
???????FillChar(UdpBuffer, 1024, 0);
???????nFrom := SizeOf(sa);
???????RecvFrom(FSocket, UdpBuffer, nLen, 0, sa, nFrom); ??????//接收數(shù)據(jù)

???????Form1.Memo1.Lines.Add(inet_ntoa(sa.sin_addr)+' : '+UdpBuffer);

???????FillChar(UdpBuffer, 2, f);
???????nFrom := SizeOf(sa);
???????SendTo(FSocket, UdpBuffer, 2, 0, sa, nFrom); ???????????//應(yīng)答
?????end ?else begin
???????//暫時沒有數(shù)據(jù)來,你可以干點別的事情 ?:)
?????end;
???CloseSocket(FSocket);
?end;
?WSACleanUp;
end;


//
// ?????????????????????????????????????????????????????????????????????????????????????//
// ???????上面的線程是用WINSOCKET API寫的,沒做差錯檢查,但你說的功能已經(jīng)實現(xiàn) ??????????//
// ?????????????????????????????????????????????????????????????????????????????????????//
//


procedure TForm1.Button1Click(Sender: TObject); ?????????????//這里 UdpSend是個TNMUDP控件
var Buffer : array[0..1024] of char;
begin
???strcopy(buffer,'Hello!');
???UdpSend.ReportLevel := Status_Basic;
???UdpSend.RemotePort := 4096;
???UdpSend.RemoteHost := '127.0.0.1';
???UdpSend.Sendbuffer(buffer,256);
end;

procedure TForm1.UdpSendDataReceived(Sender: TComponent;
?NumberBytes: Integer; FromIP: String; Port: Integer);
var Buffer : PChar ;
begin
?GetMem(Buffer, NumberBytes);
?UdpSend.ReadBuffer(Buffer^, NumberBytes);
?FreeMem(Buffer, NumberBytes);
?Memo1.Lines.Add(Inttostr(NumberBytes)+ ' Bytes');
end;


來自:鄉(xiāng)村月光, 時間:2004-8-8 14:45:58, ID:2754430
我有API的代碼,一個轉(zhuǎn)發(fā)服務(wù)器,一個隊列發(fā)送器,一個隊列接收器,用起來很方便,有人要就貼

來自:鄉(xiāng)村月光, 時間:2004-8-9 22:23:59, ID:2756448

unit UDPNet;

interface
uses Windows, Messages, SysUtils, Variants, Classes, Winsock;

// 為了提高效率,本單元所有的地址都使用winsock內(nèi)部格式,和習(xí)慣IP之間用AddrToIP和IPToAdr轉(zhuǎn)換!
const
?UDPACKETSIZE = 512; // 最大UDP包大小
?UDPXHEADSIZE = 8; ??// 數(shù)據(jù)包頭大小
?UDPXDATASIZE = UDPACKETSIZE - UDPXHEADSIZE ; // 最大數(shù)據(jù)包大小

?UDPXDATAFLAG = AC5; // 轉(zhuǎn)發(fā)數(shù)據(jù)包頭標志

?WM_TERMINATE = WM_USER + 100; // 結(jié)束線程
?WM_SENDDATA ?= WM_USER + 101; // 發(fā)送數(shù)據(jù)

type
?TSyncSignal = class(TObject) // 線程安全信號
?private
???FSignal: Boolean;
???FCritical: _RTL_CRITICAL_SECTION;
???function GetSignal: Boolean;
?public
???constructor Create(IniState: Boolean);
???destructor Destroy; override;
???procedure Reset;
???property IsSafe: Boolean read GetSignal;
?end;

?ESocketError = class(Exception);

?TSyncUDPSocket = class(TObject) // 封裝API
?protected
???FHandle: TSocket;
???FLastError: Integer;
???function GetBroadcast: Boolean;
???function GetReuseAddr: Boolean;
???function GetRecvBufSize: Integer;
???function GetSendBufSize: Integer;
???procedure SetBroadcast(Value: Boolean);
???procedure SetReuseAddr(Value: Boolean);
???procedure SetRecvBufSize(Value: Integer);
???procedure SetSendBufSize(Value: Integer);
?public
???constructor Create;
???destructor Destroy; override;
???function RecvBuffer(var Buffer; Len: Integer): Integer;
???function RecvFrom(var Buffer; Len: Integer; var Addr: Integer; var Port: Word): Integer;
???function ByteCanRead: Integer;
???function SendBuffer(var Buffer; Len: Integer): Integer;
???function SendTo(Addr: Integer; Port: Word; var Buffer; Len: Integer): Integer;
???function WaitForData(TimeOut: Integer): Boolean;
???procedure Bind(Addr: Integer; Port: Word);
???procedure Connect(Addr: Integer; Port: Word);
???procedure CreateSocket;
???procedure GetLocalHost(var IP: string; var Port: Word);
???procedure GetRemoteHost(var IP: string; var Port: Word);
???property Broadcast: Boolean read GetBroadcast write SetBroadcast;
???property Handle: TSocket read FHandle write FHandle;
???property LastError: Integer read FLastError;
???property ReuseAddr: Boolean read GetReuseAddr write SetReuseAddr;
???property SizeRecvBuffer: Integer read GetRecvBufSize write SetRecvBufSize;
???property SizeSendBuffer: Integer read GetSendBufSize write SetSendBufSize;
?end;

?TUDPXDataBuffer = packed record // 轉(zhuǎn)發(fā)數(shù)據(jù)包
???Flag: Word;
???Port: Word;
???Addr: Integer;
???Data: array [0..UDPXDATASIZE-1] of Byte;
?end;

?TUDPXServerThread = class(TThread) // 數(shù)據(jù)轉(zhuǎn)發(fā)服務(wù)器
?protected
???FUDPSock: TSyncUDPSocket;
???FUDPort: Word;
?public
???constructor Create(Port: Word);
???destructor Destroy; override;
???procedure Execute; override;
?end;

?TUDPQueData = packed record ?// 隊列數(shù)據(jù)
???Addr: Integer;
???Port: Word;
???Len: Word;
???Data: array [0..UDPACKETSIZE-1] of Byte;
?end;
?TUDPQueBuffer = array [0..1] of TUDPQueData;
?PUDPQueBuffer = ^TUDPQueBuffer;

?TUDPDataQue = record // 隊列
???Header, Tail, BufSize: Integer;
???IsFull: Boolean;
???Queue: PUDPQueBuffer;
?end;

?TUDPReceiver = class;
?TUDPDataNotify = procedure(Sender: TUDPReceiver; const Data: TUDPQueData) of object;

?TUDPReceiver = class(TThread) // 接收器
?protected
???FUDPSock: TSyncUDPSocket;
???FOnData: TUDPDataNotify;
?public
???constructor Create(Sock: TSyncUDPSocket);
???procedure Execute; override;
???property OnData: TUDPDataNotify read FOnData write FOnData;
???property UDPSock: TSyncUDPSocket read FUDPSock write FUDPSock;
?end;

?TUDPQueSender = class(TThread) // 隊列發(fā)送器,通過消息WM_TERMINATE結(jié)束
?protected
???FUDPSock: TSyncUDPSocket;
???FBuffer: TUDPDataQue;
???FSync: TSyncSignal;
?public
???constructor Create(Sock: TSyncUDPSocket; BufSize: Integer);
???destructor Destroy; override;
???function AddData(Addr: Integer; Port: Word; const Header; HLen: Word;
????????????const Data; DLen: Word): Boolean; // 要發(fā)送數(shù)據(jù)調(diào)用本函數(shù)
???procedure Execute; override;
???property Buffer: TUDPDataQue read FBuffer;
???property UDPSock: TSyncUDPSocket read FUDPSock write FUDPSock;
?end;

function AddrToIP(Addr: Integer): string;
function IPToAddr(const IP: string): Integer;

implementation

constructor TSyncSignal.Create(IniState: Boolean);
begin
?inherited Create;
?InitializeCriticalSection(FCritical);
?FSignal := IniState;
end;

destructor TSyncSignal.Destroy;
begin
?DeleteCriticalSection(FCritical);
?inherited Destroy;
end;

function TSyncSignal.GetSignal: Boolean;
begin
?EnterCriticalSection(FCritical);
?Result := FSignal;
?FSignal := False;
?LeaveCriticalSection(FCritical);
end;

procedure TSyncSignal.Reset;
begin
?FSignal := True;
end;

constructor TSyncUDPSocket.Create;
begin
?inherited Create;
?FLastError := 0;
?FHandle := INVALID_SOCKET;
end;

destructor TSyncUDPSocket.Destroy;
begin
?if FHandle <> INVALID_SOCKET then CloseSocket(FHandle);
?inherited Destroy;
end;

function TSyncUDPSocket.GetBroadcast: Boolean;
var m, n: Integer;
begin
?FLastError := 0;
?n := Sizeof(Integer);
?if GetSockOpt(FHandle, SOL_SOCKET, SO_BROADCAST, @m, n) <> 0 then
?begin
???FLastError := WSAGetLastError;
???Result := False;
?end
?else Result := m <> 0;
end;

function TSyncUDPSocket.GetReuseAddr: Boolean;
var m, n: Integer;
begin
?FLastError := 0;
?n := Sizeof(Integer);
?if GetSockOpt(FHandle, SOL_SOCKET, SO_REUSEADDR, @m, n) <> 0 then
?begin
???FLastError := WSAGetLastError;
???Result := False;
?end
?else Result := m <> 0;
end;

function TSyncUDPSocket.GetRecvBufSize: Integer;
var n: Integer;
begin
?n := SizeOf(Result);
?FLastError := 0;
?if GetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, @Result, n) <> 0 then
?begin
???FLastError := WSAGetLastError;
???Result := -1;
?end;
end;

function TSyncUDPSocket.GetSendBufSize: Integer;
var n: Integer;
begin
?n := SizeOf(Result);
?FLastError := 0;
?if GetSockOpt(FHandle, SOL_SOCKET, SO_SNDBUF, @Result, n) <> 0 then
?begin
???FLastError := WSAGetLastError;
???Result := -1;
?end;
end;

procedure TSyncUDPSocket.SetBroadcast(Value: Boolean);
var n: Integer;
begin
?FLastError := 0;
?if Value then n := -1 else n := 0;
?if SetSockOpt(FHandle, SOL_SOCKET, SO_BROADCAST, @n, SizeOf(Integer)) <> 0 then
???FLastError := WSAGetLastError;
end;

procedure TSyncUDPSocket.SetReuseAddr(Value: Boolean);
var n: Integer;
begin
?FLastError := 0;
?if Value then n := -1 else n := 0;
?if SetSockOpt(FHandle, SOL_SOCKET, SO_REUSEADDR, @n, SizeOf(Integer)) <> 0 then
???FLastError := WSAGetLastError;
end;

procedure TSyncUDPSocket.SetRecvBufSize(Value: Integer);
begin
?FLastError := 0;
?if SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, @Value, SizeOf(Integer)) <> 0 then
???FLastError := WSAGetLastError;
end;

procedure TSyncUDPSocket.SetSendBufSize(Value: Integer);
begin
?FLastError := 0;
?if SetSockOpt(FHandle, SOL_SOCKET, SO_SNDBUF, @Value, SizeOf(Integer)) <> 0 then
???FLastError := WSAGetLastError;
end;

function TSyncUDPSocket.ByteCanRead: Integer;
var n: Integer;
begin
?FLastError := 0;
?if IoctlSocket(FHandle, FIONREAD, n) = 0 then Result := n
?else begin
???FLastError := WSAGetLastError;
???Result := 0;
?end;
end;

function TSyncUDPSocket.WaitForData(TimeOut: Integer): Boolean;
var tv: TTimeVal;
???pt: PTimeVal;
???n: Integer;
???fs: TFDSet;
begin
?if TimeOut < 0 then pt := nil else
?begin
???tv.tv_sec := TimeOut div 1000;
???tv.tv_usec := (TimeOut mod 1000) * 1000;
???pt := @tv;
?end;
?FD_ZERO(fs);
?FD_SET(FHandle, fs);
?n := select(0, @fs, nil, nil, pt);
?if n = SOCKET_ERROR then
?begin
???FLastError := WSAGetLastError;
???n := 0;
?end
?else FLastError := 0;
?Result := n > 0;
end;

function TSyncUDPSocket.RecvBuffer(var Buffer; Len: Integer): Integer;
begin
?FLastError := 0;
?Result := WinSock.recv(FHandle, Buffer, Len, 0);
?if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
end;

function TSyncUDPSocket.RecvFrom(var Buffer; Len: Integer; var Addr: Integer; var Port: Word): Integer;
var a: TSockAddr;
???n: Integer;
begin
?FLastError := 0;
?Result := WinSock.RecvFrom(FHandle, Buffer, Len, 0, a, n);
?Port := ntohs(a.sin_port);
?Addr := a.sin_addr.s_addr;
?if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
end;

function TSyncUDPSocket.SendBuffer(var Buffer; Len: Integer): Integer;
begin
?FLastError := 0;
?Result := WinSock.send(FHandle, Buffer, Len, 0);
?if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
end;

function TSyncUDPSocket.SendTo(Addr: Integer; Port: Word; var Buffer; Len: Integer): Integer;
var a: TSockAddr;
begin
?FLastError := 0;
?a.sin_family := AF_INET;
?a.sin_port := htons(Port);
?a.sin_addr.s_addr := Addr;
?Result := WinSock.SendTo(FHandle, Buffer, Len, 0, a, Sizeof(TSockAddr));
?if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
end;

procedure TSyncUDPSocket.Bind(Addr: Integer; Port: Word);
var a: TSockAddr;
begin
?if FHandle = INVALID_SOCKET then
?begin
???CreateSocket;
???if FLastError <> 0 then Exit;
?end;
?FLastError := 0;
?a.sin_family := AF_INET;
?a.sin_port := htons(Port);
?a.sin_addr.s_addr := Addr;
?if WinSock.Bind(FHandle, a, Sizeof(TSockAddr)) = SOCKET_ERROR then
???FLastError := WSAGetLastError;
end;

procedure TSyncUDPSocket.Connect(Addr: Integer; Port: Word);
var a: TSockAddr;
begin
?if FHandle = INVALID_SOCKET then
?begin
???CreateSocket;
???if FLastError <> 0 then Exit;
?end;
?FLastError := 0;
?a.sin_family := AF_INET;
?a.sin_port := htons(Port);
?a.sin_addr.s_addr := Addr;
?if WinSock.Connect(FHandle, a, Sizeof(TSockAddr)) = SOCKET_ERROR then
???FLastError := WSAGetLastError;
end;

procedure TSyncUDPSocket.CreateSocket;
begin
?FLastError := 0;
?FHandle := Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
?if FHandle = INVALID_SOCKET then FLastError := WSAGetLastError;
end;

procedure TSyncUDPSocket.GetLocalHost(var IP: string; var Port: Word);
var addr: TSockAddr;
???len: Integer;
begin
?FillChar(addr, Sizeof(TSockAddr), 0);
?len := Sizeof(TSockAddr);
?GetSockName(FHandle, addr, len);
?IP := inet_ntoa(addr.sin_addr);
?Port := ntohs(addr.sin_port);
end;

procedure TSyncUDPSocket.GetRemoteHost(var IP: string; var Port: Word);
var addr: TSockAddr;
???len: Integer;
begin
?FillChar(addr, Sizeof(TSockAddr), 0);
?len := Sizeof(TSockAddr);
?GetPeerName(FHandle, addr, len);
?IP := inet_ntoa(addr.sin_addr);
?Port := ntohs(addr.sin_port);
end;

constructor TUDPXServerThread.Create(Port: Word);
begin
?inherited Create(True);
?FUDPort := Port;
end;

destructor TUDPXServerThread.Destroy;
begin
?FUDPSock.Free;
?inherited Destroy;
end;

procedure TUDPXServerThread.Execute;
var n, a: Integer;
???p: Word;
???buf: TUDPXDataBuffer;
begin
?FUDPSock := TSyncUDPSocket.Create;
?FUDPSock.Bind(0, FUDPort);
?while not Terminated do
?begin
???if FUDPSock.WaitForData(100) then
???begin
?????n := FUDPSock.ByteCanRead;
?????if n > UDPACKETSIZE then n := UDPACKETSIZE;
?????FUDPSock.RecvFrom(buf, n, a, p);
?????if (buf.Flag = UDPXDATAFLAG) and (n > UDPXHEADSIZE) then
???????FUDPSock.SendTo(buf.Addr, buf.Port, buf.Data, n - UDPXHEADSIZE);
???end;
?end;
end;

constructor TUDPReceiver.Create(Sock: TSyncUDPSocket);
begin
?inherited Create(True);
?FUDPSock := Sock;
?FOnData := nil;
end;

procedure TUDPReceiver.Execute;
var buf: TUDPQueData;
begin
?while not Terminated do
?begin
???if FUDPSock.WaitForData(100) then with buf do
???begin
?????Len := FUDPSock.ByteCanRead;
?????if Len > UDPACKETSIZE then Len := UDPACKETSIZE;
?????FUDPSock.RecvFrom(Data, Len, Addr, Port);
?????if (FUDPSock.FLastError = 0) and Assigned(FOnData) then FOnData(Self, buf);
???end;
?end;
end;

constructor TUDPQueSender.Create(Sock: TSyncUDPSocket; BufSize: Integer);
begin
?inherited Create(True);
?FUDPSock := Sock;
?FBuffer.Header := 0;
?FBuffer.Tail := 0;
?FBuffer.IsFull := False;
?if BufSize < 4 then BufSize := 4;
?FBuffer.BufSize := BufSize;
?GetMem(FBuffer.Queue, FBuffer.BufSize * Sizeof(TUDPQueData));
?FSync := TSyncSignal.Create(True);
?FreeOnTerminate := True;
end;

destructor TUDPQueSender.Destroy;
begin
?FreeMem(FBuffer.Queue, FBuffer.BufSize * Sizeof(TUDPQueData));
?FSync.Free;
?inherited Destroy;
end;

function TUDPQueSender.AddData(Addr: Integer; Port: Word; const Header; HLen: Word;
????????const Data; DLen: Word): Boolean;
var i, n: Integer;
begin
?while not FSync.IsSafe do Sleep(0);
?i := FBuffer.Tail;
?Result := not ((i = FBuffer.Header) and FBuffer.IsFull);
?if Result and ((HLen > 0) or (DLen > 0)) then
?begin
???if HLen > UDPACKETSIZE then HLen := UDPACKETSIZE;
???n := HLen + DLen;
???if n > UDPACKETSIZE then DLen := UDPACKETSIZE - HLen;
???FBuffer.Queue.Addr := Addr;
???FBuffer.Queue.Port := Port;
???FBuffer.Queue.Len := n;
???if HLen > 0 then Move(Header, FBuffer.Queue.Data[0], HLen);
???if DLen > 0 then Move(Data, FBuffer.Queue.Data[HLen], DLen);
???Inc(i);
???if i >= FBuffer.BufSize then i := 0;
???FBuffer.Tail := i;
???FBuffer.IsFull := i = FBuffer.Header;
?end;
?FSync.Reset;
?PostThreadMessage(ThreadID, WM_SENDDATA, 0, 0);
end;

procedure TUDPQueSender.Execute;
var i: Integer;
???ms: MSG;
begin
?while not Terminated do
?begin
???GetMessage(ms, 0, 0, 0);
???case ms.message of
?????WM_SENDDATA: begin
???????while (FBuffer.Header <> FBuffer.Tail) or FBuffer.IsFull do
???????begin
?????????i := FBuffer.Header;
?????????with FBuffer.Queue do
?????????begin
???????????if Len > UDPACKETSIZE then Len := UDPACKETSIZE;
???????????FUDPSock.SendTo(Addr, Port, Data, Len);
???????????Inc(i);
???????????if i >= FBuffer.BufSize then i := 0;
???????????while not FSync.IsSafe do Sleep(0); ???????????
???????????FBuffer.Header := i;
???????????FBuffer.IsFull := False;
???????????FSync.Reset;
?????????end;
???????end;
?????end;
?????WM_TERMINATE: Terminate;
???end;
?end;
end;

function AddrToIP(Addr: Integer): string;
var a: in_addr absolute Addr;
begin
?Result := inet_ntoa(a);
end;

function IPToAddr(const IP: string): Integer;
begin
?Result := inet_addr(PChar(IP));
end;

var
?WSAData: TWSAData;

procedure Startup;
begin
?if WSAStartup(01, WSAData) <> 0 then raise ESocketError.Create('WSAStartup');
end;

procedure Cleanup;
begin
?if WSACleanup <> 0 then raise ESocketError.Create('WSACleanup');
end;

initialization
?Startup;

finalization
?Cleanup;

end.



閱讀全文(305) / 評論 / 扔小紙條 / 給kraft留言 / 文件夾: delphi

轉(zhuǎn)載于:https://blog.51cto.com/525927/121286

總結(jié)

以上是生活随笔為你收集整理的在多线程中使用UDP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。