Socket_read, проблема при получении данных

slite

Новичок
День добрый. Как то попытаюсь верно сформулировать вопрос.
На php серверый сокет.

PHP:
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
set_time_limit(0);
$NULL = NULL;
$address = '192.168.1.215';
$port = 5050;
$client_socket = array();
$max = 10;
$master = socket_create(AF_INET, SOCK_SEQPACKET, SOL_TCP);
$res = true;
$res &= @socket_bind($master, $address, $port);
$res &= socket_listen($master);

if(!$res)
{
    die("Not connect, exist port or not listen \n");
}
else
{
    $read = array($master);
    $abort = false;
    $i = 0;
    while(!$abort)
    {
        $num_changed = socket_select($read, $NULL, $NULL, 0, 10);
        if($num_changed)
        {
            if(in_array($master, $read))
            {
                if(count($client_socket) < $max)
                {
                    $client_socket[] = socket_accept($master);
                }
            }
            foreach($client_socket as $key => $client)
            {
                if(in_array($client, $read))
                {
                 
                    $input = socket_read($client, 4096, PHP_BINARY_READ );
                    echo "\n ============= Razmer Paketa ==============\n";
                    echo strlen($input);
                    echo "\n ============= Razmer Vse ==============\n";
                    $errorcode = socket_last_error();
                    $errormsg = socket_strerror($errorcode);
                 
                    echo $errorcode. $errormsg;
                 
                    print_r($input);
                 
                  
                 
                    socket_close($client);
                    unset($client_socket[$key]);
                }
            }
        }
        $read = $client_socket;
        $read[] = $master;   
    }
}

Код в принципе взял с инета. Возникает проблема когда на этот порт приходят данные, которые заходят не целиком как 1 пакет, а в некоторых случаях пакет режиться, и приходят поэтапно. В случае когда пакет приходит поэтапно, пхп начинает работать только с 1 этапом прихода пакета, и соответственно запрос приходит не полный. Возможно ли сделать на пхп, так что бы он умел понимать что пакет приходит кусками и ждать весь пакет?
 

MiksIr

miksir@home:~$
Можно если вы ответите для себя на вопрос "а что является признаком окончания передачи данных"
 

slite

Новичок
даж не знаю, если смотреть через tcpdump то признаком является вот такое вот.

Код:
12:07:43.948735 IP (tos 0x0, ttl 64, id 40050, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.10.34340 > 192.168.1.215:5050: Flags [.], cksum 0x44a7 (correct), seq 1050, ack 1390, win 34028, options [nop,nop,TS val 2296673804 ecr 385909528], length 0
а вообше я подразумевал может есть какой либо параметр в котором это регулируется7
 

MiksIr

miksir@home:~$
Т.е. клиент отсоединяется сразу после окончания передачи данных? Тогда кладите данные из socket_read в буфер до тех пор, пока socket_read не вернет пустую строку ==="" или ошибку === false. И только после этого - обрабатывайте.
 

slite

Новичок
Признаться не сталкивался с такими вещями, но я так понимаю ложит в буфер через ob_start?
 

slite

Новичок
Спасибо, в принципе решил ситуацию тем что пришлось создать 2 сокета :(
 

Эд!

Новичок
Спасибо, в принципе решил ситуацию тем что пришлось создать 2 сокета :(
Была таже проблема когда писал клиент-серверное ПО для windows, пакеты резались.
Долго мучался с этим, то что они режутся это нормально, в итоге решил проблему так:
Нужно обернуть отправляемые данные в какуюто структуру, грубо говоря сделать свой протокол :D
К началу сообщения прописываешь его размер, и когда получаешь сообщение - у тебя в первом пакете будет этот размер, остальные пакеты принимай пока их суммарный вес не станет равным этому размеру.
Но честно - твой код не особо хороший, вот посмотри здесь очень неплохо реализовано: https://github.com/morozovsk/websocket
Возможно он тоже дробит пакеты, но в нем хотябы можно это легко исправить способом который я написал. Посмотри там в папку samples/chat - на основе этого примера можно быстро въехать.
 
Сверху