|
|
yyyy1234
驢有所悟
. 積分: 16
. 文章: 8
. 收花: 50 支
. 送花: 0 支
. 比例: 0
. 在線: 1592 小時
. 瀏覽: 10670 頁
. 註冊: 6923 天
. 失蹤: 5 天
|
|
|
|
|
|
|
#1 : 2014-2-18 12:23 PM
只看本作者
|
送花
(15)
送出中...
|
|
|
|
對一般熟悉 Linux TCP/IP socket programming 的programmer 來說,要做 file transfer 的工作最常使用的方法就是用 open() 將要傳送的 file 打開, , 然後用read()藉由 open() 所產生的file descriptor將讀到的 內容copy到 buffer 然後用write()藉由 socket() 所產生的file descriptor 將 buffer 的內容 透過 TCP/IP protocol傳輸到目的. 所以程式都將有類似的 routine:
Do_read(file_fd, buffer, len); // 讀file 內容的routine
Do_wite(socket_fd, buffer, len); // socket 傳輸 routine
由於 read() , write() 皆是在 user space 的 system call, 程式執行時 read() ,write() 均須將相同 buffer 的內容copy 進出 kernel space , 這不是一個非常有效率的方法, 尤其是當傳輸的檔案size相當大時 ( > 1 Gbyte) , 程式執行時間也會較久 . Linux 提供了另一個選擇: sendfile() , 它號稱是所謂的 zero-copy, 就是sednfile() system call 本身無需做buffer copy 進出 kernel space 的動作, 既能將 讀到的buffer 內容藉由 socket 傳輸到目的地, 可減少程式執行時間 . 以下是範例如何使用 sendfile() 達到和上面routine 一樣的功能.
ssize_t do_sendfile(int sock_fd, int file_fd, off_t offset, size_t count) {
ssize_t bytes_sent;
size_t total_bytes_sent = 0;
while (total_bytes_sent < count) {
if ((bytes_sent = sendfile(sock_fd, file_fd, &offset,
count - total_bytes_sent)) <= 0) {
if (errno == EINTR || errno == EAGAIN) {
// Interrupted system call/try again
// Just skip to the top of the loop and try again
continue;
}
perror("sendfile");
return -1;
}
total_bytes_sent += bytes_sent;
}
return total_bytes_sent;
}
以上的範例我是由此篇文章 (http://blog.superpat.com/2010/06 ... ndfile-and-splice/) 中 copy 出來供各位做參考.
[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
|
|