TCP/IP Server
Èá õëïðïéÞóù Ýíá áðëü TCP/IP ðïëõíçìáôéêü äéáêïìéóôÞ (Server) ÷ñçóéìïðïéþíôáò ôá TServerSocket & TClientSocket components.
(Áðáéôåßôáé íá åãêáôáóôáèåß ôï package /bin/dclsockets70.bpl)
Óôï http://delphi.about.com/od/networking/l/aa112602a.htm èá âñåßôå ðåñéóóüôåñåò ðëçñïöïñßåò ãéá ôçí ÷ñÞóç ôùí óõãêåêñéìÝíùí components.
Åðßóçò óôï http://www.overbyte.be/frame_index.h...ducts/ics.html èá âñåßôå ìéá äéáöïñåôéêÞ õëïðïßçóç áðü Indy êáé Delphi socket components.
Ãéá ðåëÜôåò (clients) èá ÷ñçóéìïðïéÞóïõìå
1. ¸íá áðëü browser ðïõ èá «÷ôõðÜåé» ìßá http äéåýèõíóç
Êþäéêáò:
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
êáé óôçí ðåñßðôùóÞ ìáò http://127.0.0.1:1024
H ðáñáðÜíù HTTP êëÞóç åìöáíßæåôáé óôïí Server óáí ôï ðáñáêÜôù êåßìåíï
Êþäéêáò:
GET / HTTP/1.1
Host: 127.0.0.1:1024
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:15.0) Gecko/20100101 Firefox/15.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en,el;q=0.8,el-gr;q=0.5,en-us;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Ï Server áðáíôÜ
Êþäéêáò:
HTTP/1.1 200 OK
Content-Length: 11
Hello World
Connection: close
[empty line]
2. Ôï telnet óôï ïðïßï èá åðéóôñÝöåôáé üôé óôÝëíïõìå (echo).
Start/Run Cmd
Óôï Dos box ðëçêôñïëïãïýìå telnet 127.0.0.1 1024
Ðëçêôñïëïãïýìå «Hello» êáé ôï áðïóôÝëëïõìå óôïí Server ìå Enter
Êþäéêáò:
Client ---------- initate connection -----------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
ÐñÝðåé íá õëïðïéçèåß ôï RFC 854, êáé äåí ìðïñåß íá óõíõðÜñîåé ìå ôï modbus Þ ôï Web server
3. To modbus client.
Èá ðñÝðåé íá åðéëÝîïõìå ãéá èýñá ðïõ áêïýåé ï Server ôçí 502.
Êþäéêáò:
|Modbus Application Protocol (MBAP) Header | Protocol Data Unit (PDU)|
|------------------------------------------+-------------------------|
|Transaction |Protocol | Length | Unit | Function | Data |
|Identifier |Identifier| Field | ID | Code | |
|--------------------------------------------------------------------|
| (2 bytes) |(2 bytes) |(2 bytes)|(1 byte)|(1 byte) | Ìåôáâëçôü |
|------------------------------------------+-------------------------|
Õëïðïßçóá, óôïí TCP/Server, Ýíá modbus client ðïõ õðïóôçñßæåé ìüíï ôéò ðáñáêÜôù functions.
03 (0x03) Read Holding Registers
ÂëÝðå MODBUS Application Protocol Specification V1.1b óåëßäá 19/51
http://www.modbus.org/docs/Modbus_Ap...ocol_V1_1b.pdf
06 (0x06) Write Single Register
ÂëÝðå. MODBUS Application Protocol Specification V1.1b óåëßäá
Statefull
¸íáò WebServer, äçìéïõñãåß ãéá êÜèå íÝá óýíäåóç Ýíá SessionId ðïõ ôï åðéóôñÝöåé óôïí Client óáí Cookie. Ìå êëåéäß áõôü ôï SessionId, ï WebServer, óõó÷åôßæåé üëç ôá äåäïìÝíá ôïõ óõãêåêñéìÝíïõ client (user name, db connection êôë)
Ï ßäéïò client, óôçí åðüìåíç åðéêïéíùíßá ôïõ, áðïóôÝëëåé ôï SessionId þóôå íá åðáíá÷ñçóéìïðïéÞóåé ôá äåäïìÝíá ðïõ üñéóå óå ðñïçãïýìåíç êëÞóç (statefull).
ÐåñéãñáöÞ ôïõ ðñïãñÜììáôïò.
Ï server áêïýåé óôçí ðüñôá 1024 êáé ãéá êÜèå íÝá óýíäåóç ðåëÜôç äçìéïõñãåß Ýíá îå÷ùñéóôü thread ðïõ èá ÷åéñßæåôáé ôçí åðéêïéíùíßá ìåôáîý ôïõò (ServerType= stThreadBlocking). Ìüëéò áðïóôáëåß ç áðÜíôçóç óôïí ðåëÜôç, ôï íÞìá ôåëåéþíåé ôçí åñãáóßá ôïõ êáé åðéóôñÝöåé óôï pool. Ç åðüìåíç êëÞóç áðü ôïí ßäéï ðåëÜôç äåí èá óõó÷åôéóèåß ìå êáìßá ðñïçãïýìåíç (stateless).
Äçìéïõñãïýíôáé íÞìáôá (threads) êëÜóçò ðïõ êëçñïíïìåß áðü ôçí TServerClientThread êáé åðéóôñÝöïíôáé óôï Server ìÝóù ôïõ event OnGetThread.
Êþäéêáò:
procedure TFrmServer.ServerGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread);
begin
SocketThread:=TSrvThread.Create(ClientSocket, Handle);
end;
TSrvThread=class(TServerClientThread)
private
fHandle:THandle;
...
protected
procedure ClientExecute; override;
public
constructor Create(aSocket:TServerClientWinSocket;
aHandle:THandle);
end;
Óôçí procedure TSrvThread.ClientExecute; äéáâÜæïõìå ôï åéóåñ÷üìåíï TCP/IP ìÞíõìá.
Ç ñïõôßíá RequestType ôï êáôçãïñéïðïéåß óáí rtHTTP, rtText, rtModBus Þ rtBinary êáé áðáíôÜåé áíÜëïãá.
Óôï http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html ðåñéãñÜöåôáé üôé ç ðñþôç ãñáììÞ ïñßæåôáé óáí
Êþäéêáò:
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
¼ðïõ Method = "OPTIONS" ; Section 9.2
| "GET" ; Section 9.3
| "HEAD" ; Section 9.4
| "POST" ; Section 9.5
| "PUT" ; Section 9.6
| "DELETE" ; Section 9.7
| "TRACE" ; Section 9.8
| "CONNECT" ; Section 9.9
| extension-method
extension-method = token
Óôï ðñüãñáììá êáôçãïñéïðïéþ ôçí êëÞóç óáí http áí ðåñéÝ÷åé ôï HTTP/1. êáé îåêéíÜåé ìå ôéò ëÝîåéò GET Þ HEAD.
Ï ÷åéñéóìüò ôïõ telnet, åßíáé äéáöïñåôéêüò. To socket ðáñáìÝíåé «áíïéêôü» Ýùò íá Ýñèåé êÜðïéïò control ÷áñáêôÞñáò.
Ôï ðñüãñáììá ÷ñåéÜæåôáé åðåêôÜóåéò åÜí êÜðïéïò èÝëåé íá êÜíåé ðñáãìáôéêÞ äïõëåéÜ ìå áõôü.
Ç ðñþôç êáé óçìáíôéêüôåñç åßíáé ç õëïðïßçóç ìéáò êëÜóçò TModbus ðïõ èá õëïðïéåß ôï modbus ðñùôüêïëëï Ýôóé þóôå ï êþäéêáò (C ìåôáöéåóìÝíç óå Pascal) íá ãßíåé óõíôçñÞóéìïò.
Êþäéêáò:
rtModBus : begin
case pbFC^ of
$03 : begin // mbfReadHoldingRegs = $03;
pa:=pword(FRequest);
pd:=pa;
inc(pa, 4); // points to Start Address
inc(pd, 5); // point to count
move(FRequest^,data[0],8);
cnt:=swap(pd^);
data[ 8]:=cnt*2;
pd:=pword(@data[9]);
for i:=0 to pred(cnt) do begin
w:=SendMessage(fHandle,REG_GET,swap(pa^)+i,0);
pd^:=swap(w);
inc(pd);
end;
size:=8+1+cnt*2;
data[5]:=2 + 1 + cnt*2;
ClientSocket.SendBuf(data,size);
end;
Ìðïñåßôå íá êáôåâÜóåôå ôçí åöáñìïãÞ êáé ôï source áðü ôï
http://www.filefactory.com/file/dftv...n/Server01_rar
Êáé ðáñáöñÜæïíôáò ôïí ìáýñï ðåéñáôÞ (Áóôåñßî óôç ÊïñóéêÞ óåë. 19)
Bugus humanum est
Êáëü öèéíüðùñï