编程菜鸟,第一次接触进程间通信,网上windows命名管道的资料太少了,很多还是错的,学起来很费劲,现在也只能说跑的通程序了,记录一下防止忘记,理解没有很深,可能会有错误,仅供参考
使用"golang.org/x/sys/windows"包实现
服务端初始化:
func initPipe(pipeName string) (windows.Handle, error) {
// 创建命名管道
pipe, err := windows.CreateNamedPipe(
windows.StringToUTF16Ptr(pipeName),
windows.PIPE_ACCESS_DUPLEX,
windows.PIPE_TYPE_MESSAGE|windows.PIPE_READMODE_MESSAGE|windows.PIPE_WAIT,
windows.PIPE_UNLIMITED_INSTANCES,
1024,
1024,
0,
nil,
)
if err != nil {
fmt.Println("Error creating named pipe:", err)
return pipe, err
}
// 等待客户端连接
fmt.Println("Waiting for client connection...")
err = windows.ConnectNamedPipe(pipe, nil)
if err != nil {
fmt.Println("Error connecting to named pipe:", err)
return pipe, err
}
return pipe, nil
}
客户端初始化:
const pipeName = `\\.\pipe\my_named_pipe`
pipe, err := windows.CreateFile(
windows.StringToUTF16Ptr(pipeName),
windows.GENERIC_READ|windows.GENERIC_WRITE,
0,
nil,
windows.OPEN_EXISTING,
0,
0,
)
if err != nil {
return
}
读写数据:
err = windows.WriteFile(pipe, m, nil, nil)
var bytes uint32
err := windows.ReadFile(pipe, buf, &bytes, nil)
其中第一个参数是读写的管道,第二个参数是读(写)数据的目标(源),第三个参数是读写数据的长度,第四个数据是表示是否是异步,正常阻塞式的命名管道设为nil即可。
写入数据时不关心写入了多少,所以第三个参数设为了nil。读数据时是通过建立一个足够大的字节数组作为缓冲区读取的,所以需要第三个参数知道读取了多长的数据来进行截取,得到正确的数据
命名管道(Named Pipes)是半双工通信机制。在半双工通信中,数据传输只能在一个方向上进行,即一方发送数据,另一方接收数据。这意味着在同一时间内,命名管道只能支持数据的单向传输,要实现双向通信,需要创建两个管道,一个用于发送,另一个用于接收。
我最开始不知道半双工通信,测试发现有时候能跑通有时候不行,后来关了一个方向的通信就好了,查了一下发现果然是半双工通信