在Go语言中使用Unix套接字

huangapple go评论94阅读模式
英文:

Unix Sockets in Go

问题

我正在尝试创建一个使用Unix套接字的简单回显客户端和服务器。在这个例子中,连接似乎是单向的。服务器可以接收来自客户端的数据,但无法将数据发送回去。如果我改用TCP连接,就可以正常工作。有人知道是什么问题吗?

服务器

package main

import "net"
import "fmt"

func echoServer(c net.Conn) {
	for {
		buf := make([]byte, 512)
		nr, err := c.Read(buf)
		if err != nil {
			return
		}

		data := buf[0:nr]
		fmt.Printf("接收到的数据:%v", string(data))
		_, err = c.Write(data)
		if err != nil {
			panic("写入错误:" + err.String())
		}
	}
}

func main() {
	l, err := net.Listen("unix", "/tmp/echo.sock")
	if err != nil {
		println("监听错误", err.String())
		return
	}

	for {
		fd, err := l.Accept()
		if err != nil {
			println("接受错误", err.String())
			return
		}

		go echoServer(fd)
	}
}

客户端

package main

import "net"
import "time"

func main() {
	c,err := net.Dial("unix","", "/tmp/echo.sock")
	if err != nil {
		panic(err.String())
	}
	for {
		_,err := c.Write([]byte("hi\n"))
		if err != nil {
			println(err.String())
		}
		time.Sleep(1e9)
	}
}
英文:

I'm trying to make a simple echo client and server that uses Unix sockets. In this example, the connection seems to be unidirectional. The server can receive data from the client, but it can't send the data back. If I use tcp connections instead, it works great. Does anyone know what's wrong?

Server

package main

import "net"
import "fmt"

func echoServer(c net.Conn) {
	for {
		buf := make([]byte, 512)
		nr, err := c.Read(buf)
		if err != nil {
			return
		}

		data := buf[0:nr]
		fmt.Printf("Received: %v", string(data))
		_, err = c.Write(data)
		if err != nil {
			panic("Write: " + err.String())
		}
	}
}

func main() {
	l, err := net.Listen("unix", "/tmp/echo.sock")
	if err != nil {
		println("listen error", err.String())
		return
	}

	for {
		fd, err := l.Accept()
		if err != nil {
			println("accept error", err.String())
			return
		}

		go echoServer(fd)
	}
}

Client

package main

import "net"
import "time"

func main() {
	c,err := net.Dial("unix","", "/tmp/echo.sock")
	if err != nil {
		panic(err.String())
	}
	for {
		_,err := c.Write([]byte("hi\n"))
		if err != nil {
			println(err.String())
		}
		time.Sleep(1e9)
	}
}

答案1

得分: 51

在你的示例客户端中,你似乎没有读取服务器的结果。当我添加代码来做这个时,我看到了来自服务器的结果。

另外,看一下我如何使用defer和break来使读取器goroutine退出。

服务器

package main

import (
	"log"
	"net"
)

func echoServer(c net.Conn) {
	for {
		buf := make([]byte, 512)
		nr, err := c.Read(buf)
		if err != nil {
			return
		}

		data := buf[0:nr]
		println("服务器收到:", string(data))
		_, err = c.Write(data)
		if err != nil {
			log.Fatal("写入错误:", err)
		}
	}
}

func main() {
	l, err := net.Listen("unix", "/tmp/echo.sock")
	if err != nil {
		log.Fatal("监听错误:", err)
	}

	for {
		fd, err := l.Accept()
		if err != nil {
			log.Fatal("接受错误:", err)
		}

		go echoServer(fd)
	}
}

客户端

package main

import (
	"io"
	"log"
	"net"
	"time"
)

func reader(r io.Reader) {
	buf := make([]byte, 1024)
	for {
		n, err := r.Read(buf[:])
		if err != nil {
			return
		}
		println("客户端收到:", string(buf[0:n]))
	}
}

func main() {
	c, err := net.Dial("unix", "/tmp/echo.sock")
	if err != nil {
		panic(err)
	}
	defer c.Close()

	go reader(c)
	for {
		_, err := c.Write([]byte("hi"))
		if err != nil {
			log.Fatal("写入错误:", err)
			break
		}
		time.Sleep(1e9)
	}
}
英文:

In your example client, you don't seem to be reading the result from the server. When I add code to do that, I see the results from the server.

Also, take a look at how I used defer and break to make the reader goroutine exit.

Server

package main

import (
	"log"
	"net"
)

func echoServer(c net.Conn) {
	for {
		buf := make([]byte, 512)
		nr, err := c.Read(buf)
		if err != nil {
			return
		}

		data := buf[0:nr]
		println("Server got:", string(data))
		_, err = c.Write(data)
		if err != nil {
			log.Fatal("Write: ", err)
		}
	}
}

func main() {
	l, err := net.Listen("unix", "/tmp/echo.sock")
	if err != nil {
		log.Fatal("listen error:", err)
	}

	for {
		fd, err := l.Accept()
		if err != nil {
			log.Fatal("accept error:", err)
		}

		go echoServer(fd)
	}
}

Client

package main

import (
	"io"
	"log"
	"net"
	"time"
)

func reader(r io.Reader) {
	buf := make([]byte, 1024)
	for {
		n, err := r.Read(buf[:])
		if err != nil {
			return
		}
		println("Client got:", string(buf[0:n]))
	}
}

func main() {
	c, err := net.Dial("unix", "/tmp/echo.sock")
	if err != nil {
		panic(err)
	}
	defer c.Close()

	go reader(c)
	for {
		_, err := c.Write([]byte("hi"))
		if err != nil {
			log.Fatal("write error:", err)
			break
		}
		time.Sleep(1e9)
	}
}

huangapple
  • 本文由 发表于 2010年5月22日 10:28:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/2886719.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定