net模块

TCP

客户端

  1. //客户端拨号
  2. pub fn dial_tcp(address string) ?TcpConn
  1. //返回tcp连接
  2. pub struct TcpConn { //实现io.Reader,io.Writer接口
  3. pub:
  4. sock TcpSocket //Socket对象
  5. mut:
  6. write_deadline time.Time
  7. read_deadline time.Time
  8. read_timeout time.Duration
  9. write_timeout time.Duration
  10. }
  1. //tcp socket对象
  2. struct TcpSocket {
  3. pub:
  4. handle int //socket的文件描述符
  5. }

客户端连接例子:

  1. module main
  2. import net
  3. import io
  4. fn main() {
  5. mut client_conn := net.dial_tcp('baidu.com:80')?
  6. defer {
  7. client_conn.close()
  8. }
  9. client_conn.write_str('GET /index.html HTTP/1.0\r\n\r\n') ?
  10. client_conn.set_read_timeout(net.infinite_timeout)
  11. result := io.read_all(client_conn) ?
  12. println(result.bytestr())
  13. }

服务端

  1. //服务端启动监听
  2. pub fn listen_tcp(port int) ?TcpListener
  1. //返回监听器/服务器对象
  2. pub struct TcpListener {
  3. sock TcpSocket
  4. mut:
  5. accept_timeout time.Duration
  6. accept_deadline time.Time
  7. }
  1. //监听器/服务器对象,调用accept以后,开始监听,返回TcpConn对象
  2. pub fn (l TcpListener) accept() ?TcpConn

服务端连接例子:

  1. module main
  2. import net
  3. import time
  4. const (
  5. server_port = 22334
  6. )
  7. fn setup() (net.TcpListener, net.TcpConn, net.TcpConn) {
  8. listener := net.listen_tcp(server_port) or {
  9. panic(err)
  10. }
  11. mut client := net.dial_tcp('127.0.0.1:$server_port') or {
  12. panic(err)
  13. }
  14. client.set_read_timeout(3 * time.second)
  15. client.set_write_timeout(3 * time.second)
  16. mut server := listener.accept() or {
  17. panic(err)
  18. }
  19. server.set_read_timeout(3 * time.second)
  20. server.set_write_timeout(3 * time.second)
  21. return listener, client, server
  22. }
  23. fn cleanup(listener &net.TcpListener, client &net.TcpConn, server &net.TcpConn) {
  24. listener.close() or { }
  25. client.close() or { }
  26. server.close() or { }
  27. }
  28. fn main() {
  29. listener, client, server := setup()
  30. defer {
  31. cleanup(listener, client, server)
  32. }
  33. message := 'Hello World'
  34. //server
  35. server.write_str(message) ?
  36. println('message send: $message')
  37. println('server socket: $server.sock.handle')
  38. //client
  39. mut buf := []byte{len: 1024}
  40. nbytes := client.read(mut buf) ?
  41. received := buf[0..nbytes].bytestr()
  42. println('message received: $received')
  43. println('client socket: $client.sock.handle')
  44. }

UDP

实现思路基本跟TCP一致

客户端

  1. //客户端拨号
  2. pub fn dial_udp(laddr string, raddr string) ?UdpConn
  1. //返回udp连接
  2. pub struct UdpConn { //实现io.Reader,io.Writer接口
  3. sock UdpSocket //Socket对象
  4. mut:
  5. write_deadline time.Time
  6. read_deadline time.Time
  7. read_timeout time.Duration
  8. write_timeout time.Duration
  9. }
  1. //udp socket对象
  2. struct UdpSocket {
  3. handle int //socket的文件描述符
  4. l Addr //local addr
  5. r ?Addr //remote addr
  6. }

服务端

  1. //服务端启动监听,返回udp连接,udp不需要accept,直接开始
  2. pub fn listen_udp(port int) ?UdpConn

服务端连接例子:

  1. import net
  2. import time
  3. fn echo_server(_c net.UdpConn) {
  4. mut c := _c
  5. c.set_read_timeout(10 * time.second)
  6. c.set_write_timeout(10 * time.second)
  7. for { //无限循环监听,接收数据后,原样返回给客户端
  8. mut buf := []byte{len: 100, init: 0}
  9. read, addr := c.read(mut buf) or {
  10. continue
  11. }
  12. c.write_to(addr, buf[..read]) or {
  13. println('Server: connection dropped')
  14. return
  15. }
  16. }
  17. }
  18. fn echo() ? {
  19. //客户端拨号
  20. mut c := net.dial_udp('127.0.0.1:40003', '127.0.0.1:40001') ?
  21. defer {
  22. c.close() or { }
  23. }
  24. c.set_read_timeout(10 * time.second)
  25. c.set_write_timeout(10 * time.second)
  26. data := 'Hello from vlib/net!'
  27. c.write_str(data) ?
  28. mut buf := []byte{len: 100, init: 0}
  29. read, addr := c.read(mut buf) ?
  30. assert read == data.len
  31. println('Got address $addr')
  32. for i := 0; i < read; i++ {
  33. assert buf[i] == data[i]
  34. }
  35. println('Got "$buf.bytestr()"')
  36. c.close() ?
  37. return none
  38. }
  39. fn test_udp() {
  40. l := net.listen_udp(40001) or { //服务端启动udp监听
  41. println(err)
  42. panic('')
  43. }
  44. go echo_server(l)
  45. echo() or {
  46. println(err)
  47. }
  48. l.close() or { }
  49. }
  50. fn main() {
  51. test_udp()
  52. }

websocket

目前websocket包放在试验性的x模块中,具体参考:x模块章节

附录:TCP网络连接示意图

TCP协议通讯流程