TCP client – PHP – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

TCP client – PHP – Fórum – Programujte.comTCP client – PHP – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
omorok0
Newbie
19. 4. 2015   #1
-
0
-

Dobrý den všem,

Potřebuji malinko pomoc s TCP clientem v PHP.

Mám fotovoltaický měnič, který zasílá v 10s intervalech data po RS 232 ve formátu:

0000.00.00 12:36  3 126.5 1 126.5 231.2    0.2 124.8 25

U měniče mám převodník: Papouch gnome Rs232 na Ethernet.

Jelikož troch programuji v PHP a mám nainstalovaný web server, hledal jsem i v php možnost přijímat data a dále je používat.

Našel jsem a dal dohromady toto:

// Vložíme soubor s připojením k databázi a funkce	
require_once '../php/db.php';
require_once '../php/function.php';


// vytvoříme socket
if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
	$errorcode = socket_last_error();
	$errormsg = socket_strerror($errorcode);
     
	die("Nelze vytvořit socket: [$errorcode] $errormsg <br />");
}

//echo "Socket vytvořen <br />";


//Navážeme spojení se vzdáleným servrem
if(!socket_connect($sock , '192.168.0.100' , 10001))
{
	$errorcode = socket_last_error();
	$errormsg = socket_strerror($errorcode);
	socket_close($sock);
     
	die("Nelze se připojit: [$errorcode] $errormsg <br />");
}
 
//echo "Spojení navázáno <br />";


//Poslat zprávu na serveru
$message = "GET / HTTP/1.1\r\n\r\n";

if( ! socket_send ( $sock , $message , strlen($message) , 0))
{
	$errorcode = socket_last_error();
	$errormsg = socket_strerror($errorcode);
     
	die("Nelze odeslat data: [$errorcode] $errormsg <br />");
}

//echo "Zpráva úspěšně odeslána <br />";


// smažeme tabulku data_ram
$del = mysql_query("DELETE FROM `data_ram` ");
if(!$del) 
{ 
	echo mysql_error() . " - " . mysql_errno(); 
}


// reset ID v data_ram
$resetID = mysql_query("ALTER TABLE `data_ram` AUTO_INCREMENT=1 ");
if(!$resetID) 
{ 
	echo 'resetID: '.mysql_error() . " - " . mysql_errno(); 
}



// načítáme data ze servru
while(true)
{
          

	
	// počká se, až budou data kompletní - celý řádek
	$x = 0;
	while ( $out = socket_read($sock, 150, PHP_NORMAL_READ) )
	{
	
		if($out != "")
		{
			// nahradíme mezery
			$intoS = str_replace(" ", ";", $out);
			
			//rozložíme
			$intoS = explode(";",$intoS);
			
			
			$into = '';
			
			$ii = count($intoS);
			
			// odstraníme poslední položku v poli, je to zalomení řádků
			$ii = $ii - 1;
		         
			for($n=0;$n<$ii;$n++)
			{
				if($intoS[$n] != '')
				{
					$into[] = $intoS[$n];
					
				} 	
				
			}
			
			// kontrola, zda jsou data a jsou úplnná
			if(isset($into[0]) AND $into[0] != '' AND isset($into[9]) AND $into[9] != '')
			{
			
				// vymaže se data_ram
				$del = mysql_query("DELETE FROM `data_ram` ");
				if(!$del) 
				{ 
					echo mysql_error() . " - " . mysql_errno(); 
				}
				
				$resetID = mysql_query("ALTER TABLE `data_ram` AUTO_INCREMENT=1 ");
				if(!$resetID) 
				{ 
					echo 'resetID: '.mysql_error() . " - " . mysql_errno(); 
				}
				
				// nahradí se v 0-té položce
				$z_into = str_replace(".", "-", $into[0]);
				$z_into = datumSQL($z_into);
				
				// zapíší se data
				$INTO = mysql_query("INSERT INTO `data_ram` SET `znak`='".$z_into."',`doba`='".$into[1]."',`stav`='".$into[2]."',`napeti_fv`='".$into[3]."',`proud_fv`='".$into[4]."',`vykon`='".$into[5]."',`sit_napeti`='".$into[6]."',`sit_proud`='".$into[7]."',`nap_vykon`='".$into[8]."',`teplota`='".$into[9]."', `date`=NOW()");
				if(!$INTO) 
				{ 
					echo mysql_error() . " - " . mysql_errno(); 
				}
				
				// provede se vždy jen jeden řádek
				if($x == 1)
				{
					
					break;
				}
				
				$x++;
			
			}
			
			
		}
		
	
	}
	
} //konec načítání dat ze servru


Funguje to jak má, ale do doby, kdy zapadne sluníčko a měnič jde spát a přestane vysílat data. Sice program nic nepíše, ale ráno jakmile se měnič probudí a začne posílat data, tak program nic nezaznamená a je kouslý??

Můj odhad je, že u části: while ( $out = socket_read($sock, 150, PHP_NORMAL_READ) )

se při přerušení zasílání dat kousne a už se neprobudí.

Nemá někdo náhodou nápad jak toto ošetřit?

Nahlásit jako SPAM
IP: 109.164.74.–
Kit+15
Guru
19. 4. 2015   #2
-
0
-

#1 omorok
Připadá mi to celé nějaké zmatené. Proč používáš socket když nemusíš? Proč zbytečně mažeš tabulku v SQL? Co tam pohledává "ALTER TABLE", který slouží pro administraci databáze? Proč tam všude máš "die"? To chceš, aby ti skript při chybě chcípnul?

Napiš to raději kratší a jednodušší, 20 řádek by ti mělo stačit. Pak se ti to přestane zasekávat. Hlavně se zbav práce se sockety. 

<?php
$data = file_get_contents('http://192.168.0.100:10001');

 Pokud to chceš mít jako seznam řádek, tak to může být ještě kratší:

<?php
$lines = file('http://192.168.0.100:10001');
Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
omorok0
Newbie
19. 4. 2015   #3
-
0
-

#2 Kit
Děkuji za odpověď,

SQL zatím neřeším, je to jen na zkoušku a data se ukládají do RAM.

Ale zajímá mě, co jsi napsal, nějak takto:

// Vložíme soubor s připojením k databázi a funkce	
require_once '../php/db.php';
require_once '../php/function.php';

// načítáme data ze servru
while(true)
{

	$lines = file('http://192.168.0.100:10001');
	
	echo $lines.'<br />';

}


echo je jen jako zástupný pro další zpracování dat...

Nahlásit jako SPAM
IP: 109.164.74.–
Kit+15
Guru
19. 4. 2015   #4
-
0
-

#3 omorok
Ten cyklus je tam zbytečný. 

<?php
require_once '../php/db.php';
require_once '../php/function.php';

$lines = file('http://192.168.0.100:10001');
$into = explode(" ", chop($lines[0]));
Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
omorok0
Newbie
19. 4. 2015   #5
-
0
-

#4 Kit
while tam mám proto, abych přijímal data co 10s a byl to nekonečný běh...

Nahlásit jako SPAM
IP: 109.164.74.–
Kit+15
Guru
19. 4. 2015   #6
-
0
-

#5 omorok
Na to PHP není stavěné. Možná proto se ti to zasekává.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
omorok0
Newbie
19. 4. 2015   #7
-
0
-

#6 Kit
je to možné.

Zítra to zkusím a uvidím. Jestli to bude fungovat, napíši

Nahlásit jako SPAM
IP: 109.164.74.–
Kit+15
Guru
19. 4. 2015   #8
-
0
-

#7 omorok
Trochu jsem si s tím pohrál a zkrátil: 

<?php
// Vložíme soubor s připojením k databázi a funkce
require_once '../php/db.php';
require_once '../php/function.php';

$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass, $dbattr);
$lines = file_get_contents('http://192.168.0.100:10001');
$into = explode(" ", chop($lines[0]));
// kontrola, zda jsou data a jsou úplná
if (isset($into[0]) && ($into[0] != '') && (isset($into[9])) && ($into[9] != '')) {
    $db->query("TRUNCATE TABLE data_ram");
    $into[0] = datumSQL(str_replace(".", "-", $into[0]));
    $sql = "INSERT INTO data_ram(znak, doba, stav, napeti_fv, proud_fv,
        vykon, sit_napeti, sit_proud, nap_vykon, teplota, date)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())";
    $insert = $db->prepare($sql);
    $insert->execute($into);
}
Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:221:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Řešení
omorok0
Newbie
21. 4. 2015   #9
-
0
-
Vyřešeno Nejlepší odpověď

#8 Kit
tak jsem zkusil:

<?php
$data = file_get_contents('http://192.168.0.100:10001');


i

<?php
$lines = file('http://192.168.0.100:10001');


a bohužel nefunguje ani jedno. Ohadnul bych, že čekají na konec souboru...

Alespoň mě to přivedlo: fsockopen

A tady je výsledný kod:

/*your proxy server address*/ 
$proxy = "192.168.0.100"; 
/*your proxy server port*/ 
$port = 10001; 
/*the url you want to connect to*/ 
$url = "http://192.168.0.100"; 
$fp = fsockopen($proxy, $port); 
fputs($fp, "GET $url HTTP/1.0\r\nHost: $proxy\r\n\r\n");



while(!feof($fp))
{
	$line = fgets($fp);
	$line = explode(" ",$line); 
	$ii = count($line);
	$ii = $ii - 1;
	$into = '';
	
	for($n=0;$n<$ii;$n++)
	{
		if($line[$n] != '')
		{
			$into[] = $line[$n];
			
		} 	
		
	} 
	
	if (isset($into[0]) && ($into[0] != '') && (isset($into[9])) && ($into[9] != ''))
	{
		$resetID = mysql_query('TRUNCATE TABLE data_ram');
		$into[0] = datumSQL(str_replace(".", "-", $into[0]));
		
		$INTO = mysql_query("INSERT INTO `data_ram` SET `znak`='".$into[0]."',`doba`='".$into[1]."',`stav`='".$into[2]."',`napeti_fv`='".$into[3]."',`proud_fv`='".$into[4]."',`vykon`='".$into[5]."',`sit_napeti`='".$into[6]."',`sit_proud`='".$into[7]."',`nap_vykon`='".$into[8]."',`teplota`='".$into[9]."', `date`=NOW()");
		
	
	}
	
	



}

fclose($fp);

Sice přes noc taky nevydrdží, ale dá se již dobře upravit atd

Děkuji moc

Nahlásit jako SPAM
IP: 109.164.74.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 25 hostů

Podobná vlákna

TCP server + multi-client — založil ingiraxo

TCP server, TCP klient v Linuxu — založil kocourOggy

Client-server-client — založil MM

Client — založil dr

FTP client — založil krajta

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý