gpt4 book ai didi

c - UNIX 套接字的缓冲写入?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:05:22 25 4
gpt4 key购买 nike

我正在打开一个套接字以直接向 X 服务器发送请求(使用 Xlib/XCB 绕过)。

#define X11_OP_REQ_CREATE_WINDOW  0x01
#define X11_OP_REQ_MAP_WINDOW 0x08
#define X11_OP_REQ_CREATE_PIX 0x35
#define X11_OP_REQ_CREATE_GC 0x37
#define X11_OP_REQ_PUT_IMG 0x48

...

struct sockaddr_un serv_addr = {0};
int socketfd = socket(AF_UNIX, SOCK_STREAM, 0); // Create the socket!
serv_addr.sun_family = AF_UNIX;
strcopy(serv_addr.sun_path, "/tmp/.X11-unix/X0", 0);
int srv_len = sizeof(struct sockaddr_un);
connect(socketfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr));

不过,我必须做一堆 write(),而且我知道对于文件来说,由于缓冲,这可能比 fwrite 慢很多,因为系统调用很昂贵。是否有适用于套接字的等效功能?甚至可以用套接字进行缓冲 IO 吗? (没关系 fwrite 也需要一个 FILE* 流,而我只有一个描述符。)

下面是发送此类请求的函数示例(使用 write)。

void x11_put_img(int socketfd, struct x11_connection* conn, uint8 format, uint32 target, uint32 gc, uint16 w, uint16 h, uint16 x, uint16 y, uint8 depth, uint32* data){
uint32 packet[6];
uint16 length = ((w*h)) + 6;

packet[0] = X11_OP_REQ_PUT_IMG | format<<8 | length<<16;
packet[1] = target;
packet[2] = gc;
packet[3] = w | h<<16;
packet[4] = x | y<<16;
packet[5] = depth<<8;

write(socketfd, packet, 24);
write(socketfd, data, (w*h)*4);

return;
}

(为简单起见,没有错误检查。)

最佳答案

正在进行缓冲写入,尽管有点不正确。例如,当您打电话时,

    write(socketfd, packet, 24);

你认为packet是什么?

现在,您可以创建一个更大的缓冲区,比如 unsigned char buffer[4096],然后 memcpy() 将您的输出放入其中,最后 write() 一次更大的数据 block 。然而,这只在一定程度上有意义,因为如果您还需要接收对您发送的消息的响应,那么除了在消息边界处中断传输没有任何优势(除非消息非常长),这将使您的代码复杂化以在发送之前缓冲多个消息。

但是请注意,write() 不能保证发送请求的全部字节数。它的返回值告诉您它实际发送了多少字节,如果是短写入,您可能需要再调用一次或多次 write() 以发送其余字节。

您可以选择将大部分内容放在 C 库中,方法是通过 fdopen() 将套接字文件描述符包装在流中,并使用流 I/O 函数。在这种情况下,您可以通过 setvbuf() 配置缓冲细节。

关于c - UNIX 套接字的缓冲写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42705111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com