How to send to and receive from socket in go asynchronously?

blov · · 801 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hello,</p> <p>I am trying to grasp go&#39;s concurrency model and I am in love with it&#39;s simplicity. Although, for my application which uses raw UDP datagrams, I need to read and write from other peers without blocking for any other. Let me elaborate more:</p> <p>Whenever I look at code samples on the Web, they all look like this:</p> <pre><code>func handleConn(client net.Conn) { b := bufio.NewReader(client) for { line, err := b.ReadBytes(&#39;\n&#39;) if err != nil { // EOF, or worse break } client.Write(line) } } </code></pre> <p>Now, although the above goroutine allows server to communicate with each client concurrently (<em>i.e.</em> without one blocking other) it does NOT allow for server to keep reading from <strong>a</strong> client while waiting to send some data at the same time. I immediately thought about using two goroutines and channels for send AND receive operations per client/peer but that seemed like an overkill.</p> <p>Concisely, <em>how can I send and receive from hundreds of UDP sockets without send operations blocking receive</em>. Thank you!</p> <hr/> <p>P.S. Source of the sample: <a href="https://gist.github.com/paulsmith/775764" rel="nofollow">https://gist.github.com/paulsmith/775764</a></p> <hr/>**评论:**<br/><br/>ChristophBerger: <pre><blockquote> <p>I immediately thought about using two goroutines and channels for send AND receive operations per client/peer but that seemed like an overkill.</p> </blockquote> <p>Why do you think so? If you want to model asynchronous behavior in Go, goroutines and channels seem the most natural way. Just recently I implemented a <a href="https://appliedgo.net/flow2go" rel="nofollow">simple dataflow net</a> this way, and the code remained really small and clear.</p></pre>_justinm: <pre><p>goroutines and channels are light enough to use for exactly this scenario.</p> <p>From the server&#39;s point of view, each client can have a send channel and a receive channel and a goroutine for handling each direction. I would definitely encourage you to try this architecture, simulate a high client count, and watch how it scales.</p> <p>Make sure the goroutine pair shares a reference to a stop/shutdown/quit channel, and close the shutdown channel whenever either send or receive detects that the client has stopped (obviously harder with UDP but presumably you have an additional control scheme for negotiating client presence).</p></pre>djherbis: <pre><p>I think my libraries might be of help with this.</p> <p>I&#39;ve written three different libraries to help with concurrent byte streaming (minimize blocking!):</p> <p>just io.Pipe, but with buffering so read/write doesn&#39;t have to block:</p> <p><a href="https://github.com/djherbis/nio" rel="nofollow">https://github.com/djherbis/nio</a></p> <p>save the entire stream so it can be fully read, by any number of readers concurrently:</p> <p><a href="https://github.com/djherbis/stream" rel="nofollow">https://github.com/djherbis/stream</a></p> <p>similar, but frees parts of the buffer that are no longer &#39;referenced&#39; by any of the readers:</p> <p><a href="https://github.com/djherbis/bufit" rel="nofollow">https://github.com/djherbis/bufit</a></p></pre>

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

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