Windows命名管道学习记录

前言

编程菜鸟,第一次接触进程间通信,网上windows命名管道的资料太少了,很多还是错的,学起来很费劲,现在也只能说跑的通程序了,记录一下防止忘记,理解没有很深,可能会有错误,仅供参考

golang实现命名管道的方式

使用"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)是半双工通信机制。在半双工通信中,数据传输只能在一个方向上进行,即一方发送数据,另一方接收数据。这意味着在同一时间内,命名管道只能支持数据的单向传输,要实现双向通信,需要创建两个管道,一个用于发送,另一个用于接收。

我最开始不知道半双工通信,测试发现有时候能跑通有时候不行,后来关了一个方向的通信就好了,查了一下发现果然是半双工通信

你可能感兴趣的:(命名管道,windows,golang)