2013-05-14 53 views
0

我正在開發使用Qt4.8.3,其中一部分涉及在QScopedPointer存儲QAbstractSocket如下的黑莓PlayBook基於網絡的應用程序內:爲什麼在嘗試將QSslSocket存儲在QScopedPointer中時發生bps_remove_fd失敗?

QScopedPointer<QAbstractSocket> nntp; 

在我的實現,我將任一QSslSocket或與QTcpSocket取決於conenction是否進行加密,即(均從QAbstractSocket繼承),

if(ssl) { 
    nntp.reset(new QSslSocket(this)); 
    (dynamic_cast<QSslSocket*>(nntp.data())))->connectToHostEncrypted(server, port); 
} else { 
    nntp.reset(new QTcpSocket(this)); 
    nntp->connectToHost(server, port); 
} 

當下去的SSL路線(非SSL工作正常!),我結束了以下運行時間錯誤:

虛擬無效QEventDispatcherBlackberry :: unregisterSocketNotifier(在QSocketNotifier *)bps_remove_fd()失敗19

該錯誤可能是黑莓相關給出的錯誤描述和代碼工作在其他平臺如預期的事實(Mac和Linux上進行測試) 。 (注意,數字19指的是文件描述符)。

任何想法,爲什麼我看到這個錯誤,我該如何解決它?

謝謝,

本。

編輯:我剛剛意識到,而不是使用指針,我可以只有一個QSslSocket,並將其當作非ssl模式下的常規QTcpSocket。更容易。我仍想知道上述錯誤的原因,但是

回答

0

我們可以看看the source code以查看發生了什麼。的unregisterSocketNotifier的源代碼是:

void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier) 
{ 
    // Unregister the fd with bps 
    int sockfd = notifier->socket(); 
    int result = bps_remove_fd(sockfd); 
    if (result != BPS_SUCCESS) 
     qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed"; 

    // Allow the base Unix implementation to unregister the fd too 
    QEventDispatcherUNIX::unregisterSocketNotifier(notifier); 
} 

並做bps_remove_fd文檔的相關性,其表示:

If the file descriptor is present it is removed from the channel. The io_handler callback and associated user data are also removed.

[returns] BPS_SUCCESS if the fd (file descriptor) was successfully removed from the channel, BPS_FAILURE with errno value set otherwise.

什麼可以使bps_remove_fd唯一的線索失敗是fd不存在,可能這意味着你的套接字沒有任何有效的文件描述符。另一個錯誤可能是因爲沒有指定的原因,文件存在但不會被刪除。

應該設置變量errno,所以如果你看看它,你可能會有更完整的錯誤描述 - 雖然我沒有嘗試,但我沒有什麼需要。

我敢打賭,bps_remove_fd的工作原理與POSIX的close(int fd)相同,所以我看看close's documentation來查看可能導致失敗的原因。它指出它在下列情況下應該/可能失敗:

  • 該參數不是有效的文件描述符(將失敗)。
  • close可能會被信號中斷(將失敗)。
  • 讀取或寫入文件系統時發生I/O錯誤(可能失敗)。

我會作出這種回答評論,因爲它並沒有真正回答你的具體情況的問題,但我希望這至少可以幫助您瞭解正在發生的事情一點點:)

+0

謝謝莫文恩 - 這真的很全面!正如我在編輯中提到的,我認識到我可以使用QSslSocket並將其視爲QTcpSocket而不是將QAbstractPointer存儲在QScopedPointer中,然後根據ssl要求重新設置它。這似乎緩解了上述問題 – 2013-05-15 11:33:56

+0

@BenJ這很好聽:) – Morwenn 2013-05-15 11:44:13

相關問題