-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNet.CrossServer.pas
134 lines (106 loc) · 3.18 KB
/
Net.CrossServer.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{******************************************************************************}
{ }
{ Delphi cross platform socket library }
{ }
{ Copyright (c) 2017 WiNDDRiVER([email protected]) }
{ }
{ Homepage: https://github.com/winddriver/Delphi-Cross-Socket }
{ }
{******************************************************************************}
unit Net.CrossServer;
interface
uses
System.SysUtils,
Net.CrossSocket.Base,
Net.CrossSocket;
type
ICrossServer = interface(ICrossSocket)
['{78865955-48EE-4354-9B03-389025839B67}']
function GetAddr: string;
function GetPort: Word;
function GetActive: Boolean;
procedure SetAddr(const Value: string);
procedure SetPort(const Value: Word);
procedure SetActive(const Value: Boolean);
procedure Start(const ACallback: TProc<Boolean> = nil);
procedure Stop;
property Addr: string read GetAddr write SetAddr;
property Port: Word read GetPort write SetPort;
property Active: Boolean read GetActive write SetActive;
end;
TCrossServer = class(TCrossSocket, ICrossServer)
private
FPort: Word;
FAddr: string;
FStarted: Integer;
function GetAddr: string;
function GetPort: Word;
function GetActive: Boolean;
procedure SetAddr(const Value: string);
procedure SetPort(const Value: Word);
procedure SetActive(const Value: Boolean);
public
procedure Start(const ACallback: TProc<Boolean> = nil);
procedure Stop;
property Addr: string read GetAddr write SetAddr;
property Port: Word read GetPort write SetPort;
property Active: Boolean read GetActive write SetActive;
end;
implementation
{ TCrossServer }
function TCrossServer.GetActive: Boolean;
begin
Result := (AtomicCmpExchange(FStarted, 0, 0) = 1);
end;
function TCrossServer.GetAddr: string;
begin
Result := FAddr;
end;
function TCrossServer.GetPort: Word;
begin
Result := FPort;
end;
procedure TCrossServer.SetActive(const Value: Boolean);
begin
if Value then
Start
else
Stop;
end;
procedure TCrossServer.SetAddr(const Value: string);
begin
FAddr := Value;
end;
procedure TCrossServer.SetPort(const Value: Word);
begin
FPort := Value;
end;
procedure TCrossServer.Start(const ACallback: TProc<Boolean>);
begin
if (AtomicExchange(FStarted, 1) = 1) then
begin
if Assigned(ACallback) then
ACallback(False);
Exit;
end;
StartLoop;
Listen(FAddr, FPort,
procedure(AListen: ICrossListen; ASuccess: Boolean)
begin
if not ASuccess then
AtomicExchange(FStarted, 0);
// 如果是监听的随机端口
// 则在监听成功之后将实际的端口取出来
if (FPort = 0) then
FPort := AListen.LocalPort;
if Assigned(ACallback) then
ACallback(ASuccess);
end);
end;
procedure TCrossServer.Stop;
begin
CloseAll;
StopLoop;
AtomicExchange(FStarted, 0);
end;
end.