2013-09-29 83 views
-2

(原始問題如下) 原來我有一個「緩慢的消費者」問題。因爲我沒有控制服務器程序,我嘗試設置 setsockopt的(m_sock,
IPPROTO_TCP,
TCP_NODELAY,
(字符*)&標誌,
的sizeof(int)的);C++,Linux,套接字發送性能

但我仍然認爲寫入套接字需要幾秒鐘的時間。 我錯過了什麼嗎? 原始發行日期: 我創建使用

m_sock = socket(AF_INET, SOCK_STREAM, 0); 

將其設置爲非阻塞套接字:

int opts = fcntl (m_sock, F_GETFL); 

opts = (opts | O_NONBLOCK); 

fcntl (m_sock, F_SETFL,opts); 

,然後發送

send(m_sock, v_pData, v_iDataSize, MSG_NOSIGNAL); 

我送大約200bytes,5在大約2分鐘後,它會產生大量的緩衝區和大量的延遲。 有沒有辦法提高發送性能?

首先編輯: 我添加更多的代碼,至於我是如何創建和使用插座:

m_sock = socket (AF_INET, 
     SOCK_STREAM, 
     0); 

if (! is_valid()) 
    return false; 

int on = 1; 
if (setsockopt (m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof (on)) == -1) 
return false; 


server = gethostbyname(host.c_str()); 
if (server == NULL) { 

    return false; 
} 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *)server->h_addr, 
    (char *)&serv_addr.sin_addr.s_addr, 
    server->h_length); 
serv_addr.sin_port = htons(portno); 

set_non_blocking(true);// Code for set_non_blocking mentioned above 


connect(m_sock,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) ; 

我使用寫入套接字:

iOut = send(m_sock, v_pData, v_iDataSize, MSG_NOSIGNAL); 
+2

顯示更多的代碼。如何計算'v_pData'?你用'gcc -Wall -g'編譯並用'gdb'和'valgrind'調試了嗎? –

+2

如果延遲是一個問題,'TCP_NODELAY'可能會有所幫助。看起來你正在以錯誤的方式使用'O_NONBLOCK'。你明白這是什麼意思嗎? – nosid

+0

它在你的問題中提到了如何創建一個大緩衝區,以及你是如何計算緩衝區大小的?你是否順利連接btw? – joe

回答

1

你看Nagle's algorithm正在進行中。

只需設置TCP_NODELAY套接字選項:

int value = 1; 
setsockopt(m_sock, IPPROTO_TCP, TCP_NODELAY, (void*)&value, sizeof(value)); 

我不認爲你需要O_NONBLOCK,但是這在很大程度上取決於你的使用情況。

+0

我已按照所述將套接字設置爲TCP_NODELAY,但由於「消費緩慢」,我仍然在寫入套接字時被阻止 – user1997268

+0

@ user1997268當您擁有「緩慢的消費者」,無論是TCP_NODELAY還是O_NONBLOCK都不會有幫助。 「慢用戶」是什麼意思?高延遲,還是消費者真的很慢消費數據? – villekulla

1

Particularily如果使用非阻塞I/O(如O_NONBLOCK),你應該使用一些複用系統調用(如.eg poll(2)或舊的和過時的select(2)),以確保您的插座確實讀寫(即在可讀時將成功地在read(2)recv(2)上,或在可寫時在write(2)send(2)上成功)。

當然,如果您有多個套接字,則需要複用多個套接字。

總之你需要一個event loop(你可以使用庫提供一個如libeventlibev ...),或有自己的周圍複用系統調用像poll ....)。即使只使用一個雙向套接字,您也需要複用其輸入和輸出(都使用阻塞或非阻塞I/O)。

閱讀一些好書,例如Advanced Linux Programming 和一些Linux Socket TutorialUnix Network Programming書。

您的問題不夠精確,無法回答。你應該給更多的代碼,或者至少給可疑係統調用上的相關痕跡。

+0

在我看來,他的問題與非阻塞I/O無關。 – villekulla

+0

我同意,但因爲你我不瞭解原始問題的細節(目前尚不清楚)。 –