<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
					xmlns:content="http://purl.org/rss/1.0/modules/content/"
					xmlns:wfw="http://wellformedweb.org/CommentAPI/"
					xmlns:atom="http://www.w3.org/2005/Atom"
				  >
<channel>
<atom:link rel="self"  type="application/rss+xml"  href="http://rulinux.net/rss_from_sect_4_subsect_6_thread_42451"  />
<title>rulinux.net - Форум - Development - CL, usocket и timeout</title>
<link>http://rulinux.net/</link>
<description><![CDATA[Портал о GNU/Linux и не только]]></description>
<image><title>rulinux.net - Форум - Development - CL, usocket и timeout</title>
<link>http://rulinux.net/</link>
<url>http://rulinux.net/rss_icon.png</url>
</image>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215449</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215449</guid>
<pubDate>Tue, 15 Mar 2016 18:36:04 +0300</pubDate>
<description><![CDATA[<p><i>>(setf (sockets:socket-option socket :receive-timeout) n)</i><br> receive-timeout это SO_RCVTIMEO, судя по <a href="https://github.com/sionescu/iolib/blob/master/src/sockets/socket-options.lisp#L199">коду</a>.<br><br>В usocket этот таймаут можно задать при создании сокета, что я и делал в первом посте, но, судя по всему, он не срабатывал на чтение, видимо только на установку соединения работает. Или в usocket там что-то придумали странное с ним, даже не знаю.</p>]]></description>
</item>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215447</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215447</guid>
<pubDate>Tue, 15 Mar 2016 16:28:15 +0300</pubDate>
<description><![CDATA[<p>С помощью iolib это делается ещё проще:<br><br>(setf (sockets:socket-option socket :receive-timeout) n)<br><br>Только будет ли read-line и другие методы для потоков корректно обрабатывать эти таймауты или это только для низкоуровщины? По-моему read-line пофиг на таймауты.<br><br>Я usocket не трогаю, т.к. он скорее мертв, чем жив.</p>]]></description>
</item>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215423</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215423</guid>
<pubDate>Sun, 13 Mar 2016 00:17:41 +0300</pubDate>
<description><![CDATA[<p>Спасибо.<br><br><i>>А лучше напиши автору, как сделать read-line с таймаутом. Может подскажет</i><br> Я решил не тревожить автора из-за такой мелочи. Посмотрел на iolib - в моём случае то же самое, что и usocket, только ещё дополнительно библиотеку какую-то компилировать, решил не трогать то, что работает.<br><br>В общем, попробовал всякие разные способы, попытался именно read-line использовать - всё как-то криво, то eof не поймаешь, то ещё чего. Плюнул, задумался, посмотрел, как люди делают, и утащил решение из hunchentoot, которое только для сокетов подойдёт, а не для произвольного стрима:<br><br><fieldset><legend>lisp</legend><div class="highlight lisp"><br />
<span class="br0">&#40;</span><span class="kw1">defun</span> set-read-timeout <span class="br0">&#40;</span>socket stream timeout<span class="br0">&#41;</span><br />
&nbsp; <span class="st0">&quot;Set timeout for read operations on stream. Taken from hunchentoot code.&quot;</span><br />
&nbsp; <span class="br0">&#40;</span>declare <span class="br0">&#40;</span>ignorable socket stream<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; #+<span class="sy0">:</span><span class="me1">ecl</span><br />
&nbsp; <span class="br0">&#40;</span><span class="kw1">setf</span> <span class="br0">&#40;</span>sb-bsd-sockets<span class="sy0">:</span><span class="me1">sockopt-receive-timeout</span> socket<span class="br0">&#41;</span> timeout<span class="br0">&#41;</span><br />
&nbsp; #+<span class="sy0">:</span><span class="me1">openmcl</span><br />
&nbsp; <span class="br0">&#40;</span><span class="kw1">setf</span> <span class="br0">&#40;</span>ccl<span class="sy0">:</span><span class="me1">stream-input-timeout</span> socket<span class="br0">&#41;</span> timeout<span class="br0">&#41;</span><br />
&nbsp; #+<span class="sy0">:</span><span class="me1">cmu</span><br />
&nbsp; <span class="br0">&#40;</span><span class="kw1">setf</span> <span class="br0">&#40;</span>lisp<span class="sy0">::</span><span class="me0">fd-stream-timeout</span> stream<span class="br0">&#41;</span> <span class="br0">&#40;</span>coerce timeout '<span class="kw1">integer</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; #+<span class="sy0">:</span><span class="me1">sbcl</span><br />
&nbsp; <span class="br0">&#40;</span><span class="kw1">setf</span> <span class="br0">&#40;</span>sb-impl<span class="sy0">::</span><span class="me0">fd-stream-timeout</span> stream<span class="br0">&#41;</span> <span class="br0">&#40;</span>coerce timeout 'single-<span class="kw1">float</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; #+<span class="sy0">:</span><span class="me1">abcl</span><br />
&nbsp; <span class="br0">&#40;</span>java<span class="sy0">:</span><span class="me1">jcall</span> <span class="br0">&#40;</span>java<span class="sy0">:</span><span class="me1">jmethod</span> <span class="st0">&quot;java.net.Socket&quot;</span> <span class="st0">&quot;setSoTimeout&quot;</span> &nbsp;<span class="st0">&quot;int&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; socket<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>* <span class="nu0">1000</span> timeout<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp;</div></fieldset><br><br>Наверное сразу надо было в эту сторону смотреть. Впрочем, потом оказалось, что у меня с ABCL и ECL проект не работает даже, ну да и ладно.</p>]]></description>
</item>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215421</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215421</guid>
<pubDate>Fri, 11 Mar 2016 17:52:17 +0300</pubDate>
<description><![CDATA[<p>А вот хуй я сам знаю!<br><br>Первое, что приходит на ум, воспользоваться стандартной функцией read-char-no-hang и делить на строки вручную. И так же вручную сделать таймаут. Но это тупо как-то.<br><br><fieldset><legend>lisp</legend><div class="highlight lisp"><br />
<span class="br0">&#40;</span>defpackage test<br />
&nbsp; <span class="br0">&#40;</span><span class="sy0">:</span><span class="me1">use</span> #<span class="sy0">:</span><span class="me1">cl</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#40;</span><span class="sy0">:</span><span class="me1">export</span> #<span class="sy0">:</span><span class="me1">run</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<br />
<span class="br0">&#40;</span>in-package <span class="sy0">:</span><span class="me1">test</span><span class="br0">&#41;</span><br />
<br />
<span class="br0">&#40;</span><span class="kw1">defun</span> process <span class="br0">&#40;</span>socket<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#40;</span>unwind-protect<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span>format t <span class="st0">&quot;Received ~A~%&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span>coerce<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>loop for char <span class="sy0">=</span> <span class="br0">&#40;</span>read-char-no-hang socket<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;while char collect char<span class="br0">&#41;</span> 'string<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#40;</span>close socket<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<br />
<span class="br0">&#40;</span><span class="kw1">defun</span> run <span class="br0">&#40;</span>port<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#40;</span>bordeaux-threads<span class="sy0">:</span><span class="me1">make-thread</span><br />
&nbsp; &nbsp;<span class="br0">&#40;</span><span class="kw1">lambda</span> <span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="kw1">let</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>socket <span class="br0">&#40;</span>sockets<span class="sy0">:</span><span class="me1">make-socket</span> <span class="sy0">:</span><span class="me1">address-family</span> <span class="sy0">:</span><span class="me1">internet</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">:</span><span class="me1">type</span> <span class="sy0">:</span><span class="me1">stream</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">:</span><span class="me1">connect</span> <span class="sy0">:</span><span class="me1">passive</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">:</span><span class="me1">local-host</span> #<span class="br0">&#40;</span>127 0 0 1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">:</span><span class="me1">local-port</span> port<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span>loop while t <span class="kw1">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw1">let</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>connection<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span>sockets<span class="sy0">:</span><span class="me1">accept-connection</span> socket<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>process connection<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span>close socket<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp;</div></fieldset><br><br>А лучше напиши автору, как сделать read-line с таймаутом. Может подскажет<br><br><a href="https://github.com/sionescu/iolib">https://github.com/sionescu/iolib</a><br><br>У себя я делал с помощью receive-from в массив октетов, с последующим преобразованием в строку и с I/O multiplexer'ом, где можно и таймаут обработать.</p>]]></description>
</item>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215420</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215420</guid>
<pubDate>Fri, 11 Mar 2016 16:15:33 +0300</pubDate>
<description><![CDATA[<p>Щас постараюсь ответить, как я делал. usocket говно, кстати, лучше iolib</p>]]></description>
</item>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215413</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215413</guid>
<pubDate>Fri, 11 Mar 2016 13:12:11 +0300</pubDate>
<description><![CDATA[<p>когда соединение хитрым образом рвётся - надо использовать <a href="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP Keepalive</a></p>]]></description>
</item>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215411</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215411</guid>
<pubDate>Fri, 11 Mar 2016 12:08:32 +0300</pubDate>
<description><![CDATA[<p>Хочется обойтись read-line ради простоты кода, конечно. <br><br>Так там сходу есть read-char-no-hang, который, впрочем, потребует того же sleep. Конкретно в стандарте CL я не нашёл чтения с таймаутом (стандарт-то от 94-го года, а составлялся, по сути, лет на 10 раньше).<br><br>В конкретных реализациях (тот же SBCL) есть и таймауты, и всё, что нужно, но мой извращённый ум почему-то решил, что стоит поискать что-то универсальное, хоть в чудесном мире общелиспа привязка к реализации является вполне нормальным и адекватным решением по множеству причин. </p>]]></description>
</item>
<item>
<title>Re:CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215410</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215410</guid>
<pubDate>Fri, 11 Mar 2016 11:49:10 +0300</pubDate>
<description><![CDATA[<p>Я ничего не понимаю в этих скобках, но может сначала считывать данные в буфер, а затем разбирать его на строки? Наверняка есть функция чтения данных с таймаутом.</p>]]></description>
</item>
<item>
<title>CL, usocket и timeout</title>
<link>https://rulinux.net/message.php?newsid=42451&amp;page=1#215409</link>
<guid>https://rulinux.net/message.php?newsid=42451&amp;page=1#215409</guid>
<pubDate>Fri, 11 Mar 2016 10:54:32 +0300</pubDate>
<description><![CDATA[<p>Надо же разбавить сие болото.<br><br>Вот, допустим, у меня есть такой код (упрощённый): <fieldset><legend>lisp</legend><div class="highlight lisp"><br />
<span class="br0">&#40;</span><span class="kw1">let</span>* <span class="br0">&#40;</span><span class="br0">&#40;</span>socket <span class="br0">&#40;</span>usocket<span class="sy0">:</span><span class="me1">socket-connect</span> server port <span class="sy0">:</span><span class="me1">timeout</span> timeout<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span>stream <span class="br0">&#40;</span>make-stream socket encoding<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#40;</span><span class="kw1">do</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>line<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>read-line stream <span class="kw1">nil</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>read-line stream <span class="kw1">nil</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw1">not</span> line<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#40;</span>do-something-with-line<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp;</div></fieldset> Всё отлично, но возникают редкие ситуации, когда соединение хитрым образом рвётся, а цикл остаётся висеть на read-line до окончания времён.<br><br>Как я понимаю, timeout срабатывает только на установление соединения, а сам read-line спокойно может заблокировать текущий поток на неопределённое время (ну или я совсем что-то не то делаю). Предполагаю, что нужен какой-то таймаут на чтение, после которого можно будет всё это дело прервать и переконнектиться. Вопрос, собственно, в том, как его кроссплатформенно (SBCL, CCL, ECL, чем больше - тем лучше) реализовать наиболее красивым способом.<br><br>Сходу находится какой-то trivial-timeout, но он страшный, мёртвый и, по заверением разработчиков, может не работать. Второй вариант - <a href="https://groups.google.com/forum/#!topic/comp.lang.lisp/wi-FoUn9-dc">решение из comp.lang.lisp</a> с бесконечным циклом и sleep. Вроде бы должно сработать, но бесконечные циклы со sleep меня пугают (хотя можно, если прижмёт).Третье - поиграть с usocket:wait-for-input, но все его применяют для серверных вещей, а у меня типа клиентское.<br><br>Также в качестве извращённого варианта можно предложить какой-нибудь watchdog thread (у меня и так многопоточная штука), который будет проверять время последнего сработавшего read-line и рестартить треды по необходимости. Но это немного странно выглядит, да и надо хэш-таблицу с локами делать.<br><br>Может кто подскажет самое изящное и простое решение?</p>]]></description>
</item>
</channel>
</rss>