2017-03-09 48 views
0

我打開一個套接字將請求直接發送到X服務器(繞過使用Xlib/XCB)。針對UNIX套接字的緩衝寫入?

#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() S,雖然,我知道,這個文件可能是慢了很多比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; 
} 

(沒有錯誤檢查,爲簡單起見。)

+0

不知道你是怎麼想的。通常,如果您通過套接字發送某個內容,則需要在發送下一個命令之前進行回覆。通過緩衝寫入,您還可以緩衝讀取和某種消息隊列。不知道這是否真的值得開銷。 – Olaf

+0

[writev](http://man7.org/linux/man-pages/man2/readv.2.html)? – rici

回答

3

做着緩衝寫道,雖然有點不正確。當你打電話時,例如,

write(socketfd, packet, 24); 

你認爲packet是什麼?

現在,您可以創建一個更大的緩衝區,例如unsigned char buffer[4096],然後memcpy()將其輸出到最終的數據塊中,並最終創建更大的數據塊。然而,這隻適用於某一點,因爲如果您還需要接收響應以發送您發送的消息,則除了在消息邊界以外分解傳輸沒有任何優勢(除非消息太長),它會使您的代碼在發送前緩衝多個消息。

但請注意,write()不保證發送請求的全部字節數。它的返回值告訴你它實際發送了多少,並且在短寫的情況下,你可能需要調用write()一個或多個額外的時間來發送其餘的字節。

你確實有把C庫大部分由VIA fdopen()包裹在一個流套接字文件描述符,並使用流I/O功能的選項。在這種情況下,您可以通過setvbuf()配置緩衝細節。

+0

我只是試着'fdopen'與'fwrite'並且慢得多。我想我會堅持'寫'。謝謝! –

+1

@étale-cohomology - 約翰的答案非常簡潔,包含重要的建議。正如他指出的那樣,'write'可能只會發送**一些**數據(但不是全部) - 這是您在本地測試時不太可能遇到的情況。在某些情況下,速度較慢可能會更安全......我實現了一個鎖定[facil.io](http://facil.io)的用戶緩衝區,它顯然比較慢,但它比意外的數據丟失要好。 – Myst