2013-02-25 31 views
1

Iam希望根據libev編寫套接字程序。我注意到https://github.com/coolaj86/libev-examples/blob/master/src/unix-echo-server.c中的幾個示例使用基於init的回調函數。例如,使用libev的套接字

main() { 

...... 
ev_io_init(&client.io, client_cb, client.fd, EV_READ|EV_WRITE); 
ev_io_start(EV_A_ &server.io); 

} 

static void client_cb (EV_P_ ev_io *w, int revents) 
{ 
    if (revents & EV_READ) 
    { 
     .... 
    } else if (revents & EV_WRITE) { 

    ...... 
    } 
} 

我的問題來自於預期的行爲,比方說,所有這些我在EV_READ當讀取存儲在一個鏈表。可以說,我一直得到包的自由流動閱讀,我會有機會進入EV_WRITE?我必須將所有通過讀取收到的所有信息發送給另一個套接字。那麼它會一次EV_READ和第二次EV_WRITE?換句話說,EV_WRITE何時會被解鎖?或者我需要阻止EV_READ以調用EV_WRITE。有人能幫助我理解這一點嗎?

+0

http://codefundas.blogspot.com/2010/09/create-tcp-echo-server-using-libev.html – enthusiasticgeek 2014-06-15 03:13:56

回答

2

要回答很短:如果你總是首先檢查一種類型的事件,然後有else if爲另一個你會面臨飢餓的風險。一般來說,我會檢查兩者,除非指定的協議使兩者都不能同時被激活。

這裏是一個更爲有問題的答案: 您問題中的鏈接不包含代碼結構,例如您的問題。客戶端https://github.com/coolaj86/libev-examples/blob/master/src/unix-echo-client.c確實有類似的回調。您會注意到它會在寫入一次時禁用寫入事件。

// once the data is sent, stop notifications that 
// data can be sent until there is actually more 
// data to send 
ev_io_stop(EV_A_ &send_w); 
ev_io_set(&send_w, remote_fd, EV_READ); 
ev_io_start(EV_A_ &send_w); 

這看起來像試圖避免管道READ事件分支不足。儘管我對libev不是很熟悉,但您鏈接的github示例看起來並不穩健。例如,static void stdin_cb (EV_P_ ev_io *w, int revents)不使用返回值getline()來檢測EOF。另外,send()recv()套接字操作返回值不會檢查讀取或寫入的數據量(儘管在本地命名管道流中金額最可能與請求的金額相匹配)。如果稍後將其更改爲基於TCP的連接,則檢查金額將至關重要。

+0

是的,我知道我用來理解的代碼不是很好,但我會非常高興,如果你可以指向我任何其他。所以,從你說的話來看,如果我檢查兩者,我應該好好去避免飢餓。謝謝。 – user2085689 2013-02-25 22:13:31

+0

是的,檢查兩者。使用'if()'語句而不是'if-else'。 – thuovila 2013-02-26 07:51:43

1

我覺得就應該避免在讀回調分開寫回調:

main() { 
    ev_io_init(&read.io, read_cb, client.fd, EV_READ); 
    ev_io_init(&write.io, writead_cb, client.fd, EV_WRITE); 
    ev_io_start(EV_A_ &read.io); 
    ev_io_start(EV_A_ &write.io); 
} 

這是我的解決方案。