How can i see whether net.Conn has next bytes to read or will block ?

xuanbao · · 187 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Lets assume i dont use any bufio or ioutil and i also dont hardCode the max buffer size and try to load things into a giant <code>[]byte</code> lets assume i am reading the connection byte by byte a single byte at a time. How can i make sure that theres next byte available something like <code>func hasNext(net.Conn)bool</code></p> <hr/>**评论:**<br/><br/>TheMerovius: <pre><p>In general, it is more idiomatic to simply block. Is there a reason you can&#39;t block?</p></pre>nefthias: <pre><p>it will block any way what i am asking is how can i make sure theres more before blocking if theres no more then i would like to send the bytes to parser etc. </p></pre>carsncode: <pre><p>It would be better to keep reading and blocking until you&#39;ve caught some parseable block (depending on your data format - so maybe newlines or semicolons or whatever works in your situation), then send that to the parser. This solves the blocking issue and helps to decouple the parser from the network handling.</p></pre>nefthias: <pre><p>In my case we are using binary protocol and sending the length in the 3rd byte so its no problem but i just wondered if theres any other way to do it without actually sending the length </p></pre>nefthias: <pre><p>somthing like </p> <pre><code>as long as (hasNext) read end doSomethingWithFullData </code></pre> <p>```</p></pre>carsncode: <pre><p>There has to be some indicator in the stream, generally: a preceding length value; a delimiter/end of data indicator; or closing the connection after transmission is complete. There is no way for a connection itself, devoid of protocol to know if more data is coming (other than the connection being closed). At <em>best</em> it can know if there&#39;s data in its buffer.</p></pre>TheMerovius: <pre><p>There is a ioctl (SIOCINQ) you can use to see how much data is in the kernel inbound socket buffer; but note, that this will only tell you how much data the kernel has buffered you haven&#39;t read, it doesn&#39;t tell you whether or not the other side of the connection will send <em>more</em> data eventually - that part is fundamentally unknowable.</p> <p>You know that the stream is done, when you get an EOF - until then, the best and idiomatic way to handle this is to blockingly read as much data as you get and hand it over piece-wise and do the framing on the application level.</p> <p>You probably want your parser to take an <code>io.Reader</code> and just pass the connection directly. It&#39;ll be fine.</p></pre>nefthias: <pre><p>oh yes that is what i am seeking for of course nobody knows whether the other party will send more messages or not but i would like to know how far i consumed of the message and how much is waiting to be consumed. I will see ioctl but cna you be more specific and is it cross platform ?</p></pre>TheMerovius: <pre><p>I still do not understand why you can not just block. Go goes to great length to make this as fast and efficient as possible and will do all kinds of polling itself.</p> <blockquote> <p>cna you be more specific</p> </blockquote> <p>Not really, I don&#39;t know enough about network programming myself.</p> <blockquote> <p>and is it cross platform ?</p> </blockquote> <p>Definitely not.</p></pre>nefthias: <pre><p>oh not being cross platform makes it really not reliable. this is a hypothetical question though in our system we use length as a parameter but anyway it could be really nice</p></pre>pdffs: <pre><p>What do you mean by &#34;if theres no more&#34;? You absolutely need to delineate your message boundaries somehow.</p> <p>You <em>could</em> push the bytes into a channel in a goroutine, then use <code>select</code> to determine if there&#39;s anything to be read from the channel at this precise moment, but that&#39;s not likely to give you what you think you want - what happens if there&#39;s a delay sending data over the socket, packet-loss or whatever? You&#39;ll end up sending a partial message to your parser. You can&#39;t rely timing to handle this.</p></pre>sethammons: <pre><p>Like others have said, without protocol information, you simply can&#39;t know if more data is or is not coming. You need a blocking read. You can make a read timeout or similar. There is also Peek() which will let you know the next n bytes without advancing the reader, but you can only peek on what has already been sent. You can&#39;t know the future.</p></pre>nefthias: <pre><p>where is the Peek located exactly ? I couldn&#39;t find it in net package.</p></pre>sethammons: <pre><p>Look in the bufio package</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

187 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传