Gå til innhold

TCP Server i php, innspill? (Sende systemXMLInfo)


Anbefalte innlegg

Hallo

Jeg holder på med et lite prosjekt som heter systemXMLInfo, prosjektet går ut på å lage en standard for system info sending. Formatet er i XML

Og i tillegg til å skrive regler så har jeg laget litt små script i bash, og nå en server i php

Serveren er liten og kjapp, hver som kobler seg til på riktig port får nyeste system info (eller faktisk annen data siden servern bare sender innholdet fra en fil)

 

Hver tilkobling bruker under 1 sekund på å gjennomføres (DNS er egentlig ikke tatt med, men jeg får denne tiden med DNS). Med time i Linux så fikk jeg disse resultatene på NC

real	0m0.124s
user	0m0.008s
sys	 0m0.000s

 

Grunnen til at jeg skrev dette var fordi jeg var lei av HTTP, det skal så mye unødvendig til pluss at det er ekstra arbeid å hente via feks wget i script (tar tid å koble seg opp også).

Her har du en enkel kommando.

Linux/Unix

nc <HOST> <PORT>
eller
telnet <HOST> <PORT>

Windows (som jeg vet om)

telnet \\<HOST> <PORT>

 

Man kan forresten prøve serveren ved å koble seg til sxml.alectbm.no på port 8010

 

I Linux/Unix så kan man bruke NC kommandoen til å stenge servern

echo <SHUTDOWN COMMAND> | nc <HOST> <PORT>

Server koden

 

 

 

Flyttet til #11

 

 

 

Jeg ønsker altså da innspill og forslag til forbedringer

 

Forslag XML kode for prosjektet

http://sxml.alectbm.no/proposal1.xml (XML fil)

http://sxml.alectbm.no/proposal1.xsd (XML regler)

Ønsker noen å hjelpe meg med utviklingen av dette prosjektet så er det bare å ta kontakt

Endret av AlecTBM
Lenke til kommentar
Videoannonse
Annonse

Vell, nå har det seg sånn at php-cli ikke bruker webserveren, så er kun PHP som kjører

Men skal være enig i at PHP ikke er det kjappeste og letteste språket som finnes, vet ikke hvordan dette vil fungere med mange klienter

 

Grunnen til at jeg brukte PHP istedenfor feks Perl er at jeg ikke kan Perl, bare PHP

Lenke til kommentar

I og med at du baserer deg på at en klient får en viss tid på seg til å sende en melding før du tar en avgjørelse på at den ikke har tenkt å sende data, ville jeg ha gått for en løsning med select. Slik det er nå, vil man nok lett kunne blokkere tilgangen til tjenesten med å starte opp mange telent sesjoner mot tjenesten, uten å sende data. Hvis jeg starter 100 sesjoner på en gang, vil ingen andre kunne koble til på 200*100 msec (20 sekunder?) Dog det kommer vel an på hvor stor kø som er på tjenersiden.

 

Nå har jeg ikke brukt select i PHP før, så er tilbudet der: socket_select.

 

Med select() så kan du ta imot andre klienter mens du venter på input fra den første klienten. Også kan du sette en lenger timeout uten at det går ut over nestemann.

 

select er litt vanskelig å forstå, men er en fin måte å tillate flere klienter til tjeneren uten å bruke tråder eller forke

Endret av footnote
Lenke til kommentar

jepp, alle språk har vel et interface til select, som er et BSD systemkall, som tar som parametre de IO kildene du forventer at det skal skje noe på. En socket eller standard input f.eks. Den blokker inntil noe skjer, f.eks at du skriver en linje tekst og trykker enter, eller at noen gjør en connect til socket, eller skriver til socket.

Lenke til kommentar

noe jeg stusser litt på i koden din Jckf

 

my $close_me = 0;



					my $input = <$handle>;

					# Behandle input. Sett $close_me til 1 for å lukke tilkoblingen.



					if ($close_me == 1) {

							$select->remove($handle);

							$handle->close();

}

 

Vil ikke denne gjøre at $close_me aldri blir 1?

 

footnote: Du sier noe der, denne er nok ganske "lett" å blokkere

Hadde det bare kunne gått ann å få dette til i bash, hehe

 

Takker for innspill

Lenke til kommentar

Kom på en liten ting her nå, det er jo egentlig ikke noe behov for å se etter en shutdown kommando.

 

*fjerne*

 

Dette vil jo gjøre at det ikke blir såpass stor ventetid, men ved høy trafikk så vil det alikevell fort ta lengre tid

Men så spørs det hvor mange av gangen det er behov for, eneste jobben til denne er jo å sende XML data

 

 

Endret koden:

 

 

#!/usr/bin/php
<?php
/**			systemXMLInfo php server version 0.5					**/
/** This server deliver systemXMLdata to any client that			**/
/** connects to the right address trough the port spesified			**/
/** under. 															**/
/**																	**/
/**	This server handles one client at the time, 					**/
/**	so if multiple clients try to connect at the same time			**/
/** they will be put in a que. The waiting time is not long			**/
/**	depending on the networkload, normaly it takes under 			**/
/** one second to get data. Well, 1 second is unormal long			**/
/** time.															**/
/**																	**/
/**	--Alexander Frøyseth ([email protected]) aka AlecTBM	**/
/**						License is not settled yes					**/
/** Questions and ideas can be emailed to me						**/



// Set time limit to indefinite execution
set_time_limit (0);

// Set the ip and port we will listen on
$address = '127.0.0.1';
$port = 3333;

// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
while(!@socket_bind($sock, $address, $port)) { //If port is taken, retry
echo 'Port not ready, waiting for 5 sec';
for($i=0; $i<5;$i++){
	sleep(1);
	echo ' .';
}
echo "\n";
if($a++ > 60) {
	die('Sorry, but it dont look like the port is going to be freed');
}
}

// Start listening for connections
socket_listen($sock);
echo 'Server started!'."\n";

while(true) { //"Infinity" loop

$client = socket_accept($sock); //Look for client
socket_getpeername($client,$remoteAddress,$remotePort); //Get IP adress and port ()
if($client != FALSE) {
	echo 'Connection from '.$remoteAddress .':'.$remotePort."\n";
	echo 'Sending data'."\n";
	$sent = socket_write($client,file_get_contents('path/to/systemXML/file.xml')); //Send systemXMLInfo
	echo 'Sent '.$sent.' Bytes'."\n";
	socket_shutdown($client,2); //Close client socket to make room for a newone
	socket_close($client);
	echo 'Disconnected'."\n\n";
}
}

?>

 

 

 

Nye tider:

real 0m0.149s

user 0m0.000s

sys 0m0.004s

 

Ligger her omkring 150

Endret av AlecTBM
Lenke til kommentar
Hadde det bare kunne gått ann å få dette til i bash, hehe

 

Det går jo forsåvidt an, sålenge du bare skal "serve" en fil. Ta en titt på inetd/xinetd. Der kan du sette opp at den lytter på en bestemt port, fyrer et script når det kommer en connection, og sender ut stdout fra scriptet.

 

Ellers ville jeg nok valgt Python eller Perl fremfor PHP.

Lenke til kommentar

Man bare echoer ja, men til ditt formål så er det jo ikke så mye mer som skal til, ettersom jeg forsto. (Man mangler selvsagt en del utvidelsesmuligheter senere, da. :) )

 

Hvis du har tenkt å lære deg et nytt språk, ville jeg ihvertfall tatt en titt på Python. Ruby er også litt moro. Perl er utrolig kraftig, men kan være litt "tungt", spesielt om man er dårlig på å kommentere og skal lese koden igjen etter et år eller to..

Lenke til kommentar

Socketprogrammering i helt plain C er ihvertfall ingen stor heksekunst. Lett å gå i fella med pekere osv til å begynne med (fort gjort å få ting til å kræsje), men det er ikke så mange linjene med kode som skal til for å få opp en bitteliten server.

 

Manualen i linux/unix inneholder en del informasjon.

$ man socket
$ man connect
$ man accept
$ man bind

..osv osv.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...