[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Асинхронный TCP сервер
DarkSeller
Всем привет. Если вас не затруднит, можете дать код неблокирующего TCP сокета-сервера, который отсылает обратно то, что ему прислали? В гугле не -нашёл только клиентские сокеты, но это не то
caballero
неблокирующего что? Почему TCP сервер должен что то блокировать
DarkSeller
ну, чтобы к нему могли подключаться одновременно несколько клиентов
DarkSeller
всем спасибо. нашёл
http://i-novice.net/sokety-v-php/
inpost
DarkSeller
node.js + socket.io, сокеты серверные + кроссплатформенные.

_____________
Обучаю веб-программированию качественно и не дорого: http://school-php.com
Фрилансер, принимаю заказы: PHP, JS, AS (видео-чаты). Писать в ЛС (Личные сообщения на phpforum).
caballero
Цитата
ну, чтобы к нему могли подключаться одновременно несколько клиентов

К любому TCP серверу может подключатся много клиентов - например у к апачу к которыму ты щас подключаешся.
Потрудись в следующий раз внятно сформулировать чего хочешь.
I++
Говнокод
 |
\|/

http://i-novice.net/sokety-v-php/


1. Отсутствует буферизация чтения, во временную переменную. (Данные могут приходить не целиком, а кусками, их нужно класть во временную переменную, после чего разбивать по спецсимволу.)
2. Отсутствует буферизация записи в сокет. (Сокет не обязан записать все данные, он может записать 1 байт из 100000000000 байтов, которые ему дали, а так как сокет не блокирующий, к тому времени еще данные на запись появляются. Требуется стек.)
3. Нету отлова WSAEWOULDBLOCK и других прелестей.
4. Отсутствие полной проверки на ошибки, в том числе через сокгетопт SO_ERROR. Отсуствие таймаутов.

Если все это не учесть могут выползать баги мешками.

Это конечно личное ИМХО, но я тут решил серьезно изучить сокеты на php.

Вот запиливаю функцию которая правильно бы записывала в сокет.

Тут функция пока не поддерживает множественные коннекты, может работать только с 1 подключением. И буфер 1. При множественных конектах нужно делать общий буфер наверно в виде массива, но как по нормальному определить размер выделенной памяти под этот массив... сказать сложно.

Работает оно следующим образом. Когда мой некоторый код, записывает данные, на самом деле он буферизируется, вызовов write_socket может быть за 1 итерацию цикла много, и чтобы лишний раз не дергать буферизирую все данные, затем, когда происходит новая итерация цикла вызываю write_socket(null, true) и все данные которые уместились в socket_tcp_sendspace (При условии, что буфер записи свободен) разом отправляются, естественно данные фрагментируются, и при следующей итерации уже остаток доставляется. Так же пока не допилил отлов WSAEWOULDBLOCK, чтобы более корректно было. Так же перед write_socket(null, true) стоит socket_select проверяющий доступность сокета на запись, зачем дергать функцию, если на другом конце стоит воздушный модем с пингом 40к и каналом 16 кб сек.

	private function write_socket($cmd, $buffered = false)
{
// Add control WSAEWOULDBLOCK!

if($buffered === false)
{
if(strlen($this->write_buffer) < $this->options['write_buffer_size'])
{
$this->write_buffer .= $cmd.'|';
return true;
}
else
{
return false; // sock throttling. ignore data.
}
}

else
{
if($this->write_buffer === null)
return false;

$data_length = strlen($this->write_buffer);

if($data_length < $this->socket_tcp_sendspace)
$current_data = &$this->write_buffer;
else
$current_data = substr($this->write_buffer, 0, $this->socket_tcp_sendspace);

$sent_length = socket_write($this->handle_connection, $current_data, $this->socket_tcp_sendspace);

if($data_length === $sent_length)
$this->write_buffer = null;
else
$this->write_buffer = substr($this->write_buffer, $sent_length);

return true;
}
}


$this->socket_tcp_sendspace = socket_get_option($this->handle_connection, SOL_SOCKET, SO_SNDBUF);

Так получаю размер буфера отправки. На винде он примерно 8к с копейками, на юниксах (фрибизди) можно буфер побольше сделать у меня 32к стоит. И вообще шоколад =)
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.