Максимальный размер передаваемых данных через сокет

stanlee

Новичок
Максимальный размер передаваемых данных через сокет

пытаюсь отправить текст через сокет - обрезает
замерил то что получил - 8688
несколько мег передалось без проблем
 

Вурдалак

Продвинутый новичок
stanlee, socket_read() по умолчанию считывает только то, что успело прийти на сокет.
 

Вурдалак

Продвинутый новичок
Ну ты отправляешь данные. Они оказываются на удалённой машине не сразу. Что накопилось в очереди, то и функция тебе возвращает. Т.е. есть два варианта: либо функция ждёт до посинения пока не накопит 40960 байт, либо возвращает только то, что уже есть. Тебя что устраивает?
 

stanlee

Новичок
данные передаются почти моментально
демон запущен в консоли и постоянно опрашивает порт
видно что он получает
а получает он не все

все что ниже 8кб нормально обрабатывается, а выше вылетает с ошибкой

не пойму что режет текст

это все мешает работе, т.к. больше вариантов связываться между двумя серверами без веб сервера в php вроде нет.

-~{}~ 25.10.10 00:23:

странная хрень
в зависимости от изменения скорости чтения сокета данные принимаются с разной длиной

первый раз с таким сталкиваюсь
 

Вурдалак

Продвинутый новичок
Ну в любом случае неправильно полагаться на скорость. Можно отправлять сначала длину отправляемых данных, затем сами данные:
PHP:
socket_write($socket, pack('N', strlen($request)), 4);
socket_write($socket, $request, strlen($request));

// ...

$rcv = unpack('Nlength', socket_read($socket, 4));
$length = $rcv['length'];

$data = '';

while( $length > 0 ) {
    $buff = socket_read($socket, $length);
    $length -= strlen($buff);
    $data .= $buff;
}
-~{}~ 25.10.10 00:28:

Ну тут да, тоже socket_read($socket, 4) «неправильно» используется, но уж 4 байта это не 8 килобайт.
 

stanlee

Новичок
так у меня сокет постоянно опрашивается и если там что то появляется то идет чтение
смысл передавать вначале длину, если я заведомо задрал величину больше передаваемого текста

но дело в том что изменив скорость чтения длина получаемых данных уменьшилась и осталась на одном значении - 2896 символов
 

Вурдалак

Продвинутый новичок
Автор оригинала: stanlee
смысл передавать вначале длину, если я заведомо задрал величину больше передаваемого текста
— ну и как ты узнаешь, что все отправляемые данные пришли?

Сколько ты получишь, если напишешь, скажем
PHP:
$d1 = socket_read($socket, 666666);
usleep(2000);
$d2 = socket_read($socket, 666666);
var_dump(strlen($d1), strlen($d2));
?
 

stanlee

Новичок
по идее должен прочитать все до 666666, а сколько там будет уже от отправленного текста зависит

ели отправить 4 символа, то передатся же 4 символа и сокет закроется, независимо от того сколько мы выставили в socket_read, если конечно атм не меньше 4
 

Вурдалак

Продвинутый новичок
stanlee, для удалённого сервера нет разницы как ты пошлёшь данные. Так:
PHP:
socket_write($socket, 'abcxyz', 6);
или так:
PHP:
socket_write($socket, 'abc', 3);
usleep(1000); // делаем что-то
socket_write($socket, 'xyz', 3);
Он этого не знает.

-~{}~ 25.10.10 01:15:

Поэтому нужно «договориться» о каком-то формате передаваемых данных, чтобы адресат понимал закончили ли передавать данные или ещё подождать.
 

stanlee

Новичок
так для завершения есть же функция
socket_close
по идее должно приниматься все пока я ее не вызову
 

Вурдалак

Продвинутый новичок
Т.е. ты считаешь, что socket_read() будет ждать до тех пор, пока на отправляемой стороне не закроется соединение?
 

fixxxer

К.О.
Партнер клуба
man 2 read:

Upon successful completion, read(), readv(), and pread() return the number of bytes actually read and placed in the buffer. The system
guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left before the
end-of-file, but in no other case.
 

Вурдалак

Продвинутый новичок
fixxxer, а причём тут read()/readv()/pread()? Там же через recv() происходит приём данных.

-~{}~ 25.10.10 18:27:

Надо будет попробовать
PHP:
function sendData($socket)
{
    socket_write($socket, pack('N', strlen($request)));
    socket_write($socket, $request);
}

function receiveData($socket)
{
    if( socket_recv($socket, $buff, 4, MSG_PEEK | MSG_DONTWAIT) === 4 ) {
        socket_recv($socket, $buff, 4, MSG_WAITALL);
        $rcv = unpack('Nlength', $buff);
        $length = $rcv['length'];

        socket_recv($socket, $buff, $length, MSG_WAITALL);

        return $buff;
    }

    return false;
}
 

fixxxer

К.О.
Партнер клуба
Я в код именно php-шного socket_recv() не смотрел, но обычно все используют именно read(). recv() это старый системный вызов, оставленный для совместимости; он с приколом: If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from. Ну и - касаемо сабжа - в остальном то они идентичны.
 
Сверху