2011-08-04 86 views
0

我在網絡編程的工作,我有這樣的代碼什麼可能導致無限循環錯誤

void WorkHandler::workLoop(){ 
. 
. 
. 

while(1){ 
    if(remainLength >= MAX_LENGTH) 
     currentSentLength = send(client->getFd(), sBuffer, MAX_LENGTH, MSG_NOSIGNAL); 
    else 
     currentSentLength = send(client->getFd(), sBuffer, remainLength,MSG_NOSIGNAL); 


if(currentSentLength == -1){ 
    log("WorkHandler::workLoop, connection has been lost \n"); 
    break; 
} 
sBuffer += currentSentLength; 
remainLength -= currentSentLength; 

if(remainLength == 0) 
    break; 
    } 
} 

而且,我創建一個子線程這樣

bool WorkHandler::initThreads(){ 

for(int i=0; i < m_maxThreads; i++){ 
    pthread_t *thread(new pthread_t); 
    m_workThreadList.push_back(thread); 

    if(pthread_create(thread, NULL, runWorkThread, reinterpret_cast<void *>(this))!=0){ 
     log("WorkHandler::initThreads, pthread_create error \n"); 
     return false; 
    } 

    pthread_detach(*thread); 
} 

return true; 

}

void* WorkHandler::runWorkThread(void *delegate){ 
    printf("WorkHandler::runWorkThread, called\n"); 

    WorkHandler *ptr = reinterpret_cast<WorkHandler*>(delegate); 
    ptr->workLoop(); 
    return NULL; 
} 

我在gdb上運行這個代碼,它並沒有炸燬,但它被卡在if then else循環中的第二個發送函數中。我將日誌語句放在每一行中,並在第二個發送函數上方打印日誌並停止。

currentSentLength = send(client->getFd(), sBuffer, remainLength, MSG_NOSIGNAL); 

什麼可能會導致此問題,以及如何解決此問題? 在此先感謝..

+1

我懷疑這是你的主要問題,但同時應該說'while(remainLength> 0)'。每當我看到'while(true)'或同等的東西時,我都會不寒而慄。儘管這可能與由於某種原因維持長時間負值相關;你只有在== 0時纔會破壞。 – Flynn1179

+0

檢查客戶端是否讀取數據 –

+1

我認爲這太微不足道了,但如果currentSentLength爲0或負數,或者如果剩餘長度變爲負數,while循環將會卡住。 – Johan

回答

2

如果內核緩衝區已滿並阻塞IO發送,則block將阻塞,直到客戶端已讀取數據。你發大塊嗎?如果是這樣,請檢查您的客戶。

如果您不信任客戶端(他們可能會濫用此功能來執行拒絕服務攻擊),有幾種方法可以正確執行此操作:套接字上的輪詢(超時)以實現可寫性,使用超時發送,使用非阻塞I/O,...

1

我猜你調用send()用大小爲負... 您的測試退出,而應該是 remainLength < = 0 而不是 remainLength == 0

+0

爲什麼它會是負面的? –

+0

@yi_H:因爲'stillLength - = currentSentLength;'可能變成負數,這取決於send()返回的結果。 –

+0

不行,'send'不能發送超過你請求的內容。 –

相關問題