2011-04-01 180 views
1

我寫了一個服務器和一個使用重疊命名管道的客戶端。我的問題主要是用Readfile()和GetOverlappedResult()。使用重疊的命名管道的服務器:如何使用GetOverlappedResult()和ReadFile()?

請注意,該程序是一個測試代碼。它將在稍後集成到一個框架中(我將linux代碼移植到使用AF_UNIX地址族進行套接字連接的unix)

我描述了服務器部分。我有2個線程:

1)主線程打開重疊的命名管道,然後通過WaitForMultipleObjects()循環。 WaitForMultipleObjects()等待3個事件:第一個等待客戶端連接。第二次讓我徹底退出該計劃。在ReadFile()中掛起操作時,第三個信號會發出信號。

2)第二個線程在客戶端連接時啓動。它在ReadFile()上循環。

這裏是服務器代碼:

http://pastebin.com/5rka7dK7

我主要用來MSDN文檔(命名管道服務器使用重疊I/O,命名管道客戶端),該SDK,以及Internet上的其他文檔,寫該代碼。在[1]中查看客戶端代碼。客戶端代碼需要一些愛,但現在,我專注於使服務器完美工作。

有在服務器代碼4個功能​​(i忘記,顯示錯誤消息的功能):

一個)svr_new:它創建的重疊命名管道和3點的事件,並調用ConnectNamedPipe()

b)中svr_del釋放所有資源

c)中_read_data_cb:調用ReadFile的()

d)的main()函數(主線程),其遍歷WaitForMultipleObjects的(線程)

我的目標是在客戶端斷開連接時(ReadFile()失敗並且GetLastError()返回ERROR_BROKEN_PIPE)以及數據來自客戶端時,在_read_data_cb()中檢測。

我不明白:

  • 我應該叫GetOverlappedResult()?
  • 如果是,在哪裏?當ReadFile()失敗並且GetLastError()返回ERROR_IO_PENDING(粘貼的第50行)時?當WaitForMultipleObjects()返回時(粘貼的第303行,我在那裏註釋了代碼)?別的地方 ?
  • 當WaitForMultipleObjects()返回(粘貼的第302行)時,我執行ReadFile()事件的ResetEvent。這是稱呼它的正確地點嗎?

對於I粘貼的代碼,這裏是如果客戶端發送這些24個字節(的ReadFile()緩衝區的大小爲5個字節的結果。我intentionnaly設定該值來進行測試,以做什麼,如果客戶端發送一些數據大於ReadFile()緩衝區)

消息:「salut,c'est le client!「

輸出:

$ ./server.exe 等待客戶... WaitForMultipleObjects的:0 客戶端連接(1) WaitForMultipleObjects的:2 *的ReadFile:5個 WaitForMultipleObjects的:2 * ReadFile的:5 WaitForMultipleObjects的:2 *的ReadFile:5個 WaitForMultipleObjects的:2 *的ReadFile:5個 WaitForMultipleObjects的:2 * ReadFile的:4

注意:WaitForMultipleObjects()可以被稱爲小於它,它似乎是隨機的。因此,在我的代碼中,我沒有調用getOverlappedResult(),ReadFile()成功(il讀取5 * 4 + 4 = 24字節),但是我不知道讀取操作何時完成。

注意:我添加一個printf(),當ReadFile()失敗並返回ERROR_IO_PENDING時,printf()被無限期調用。

另外,客戶端發送2條消息。上面的一個,另一個3秒鐘後。第二條消息永遠不會被讀取,並且ReadFile()失敗,錯誤爲ERROR_SUCCESS ...(所以準確地說,ReadFile()返回FALSE並且GetLastError()返回ERROR_SUCCESS)

所以,我完全失去了。我在MSDN上的互聯網上搜索了幾小時的SDK代碼(Server32.c和Client32.c)。在我的具體情況下,我仍然不知道該怎麼做。

因此,有人解釋我如何使用GetOverlappedResult()(如果我必須使用它)知道如何檢查讀取操作是否完成,以及在哪裏?甚至,如果有人可以修復我的代碼:-)我給了代碼,以便每個人都可以測試它(我在網上找到很多文檔,但幾乎總是不準確: - /)

謝謝你

[1] http://pastebin.com/fbCH2By8

回答

1

看看I/O完成端口。在我看來,這是接收和處理有關Windows重疊操作通知的最有效方式。所以基本上你需要在阻塞和非阻塞模式下使用GetQueuedCompletionStatus和GetQueuedCompletionStatusEx來處理新的完成事件,而不是隨時調用GetOverlappedResult。事實上,你甚至可以完全擺脫WaitForMultipleObjects。

另外,您定位的是哪種Unix?在Solaris中有一個非常相似的抽象。查看man port_create。

不幸的是,在Linux中沒有任何類似的東西。信號(包括實時)在某種程度上可用作等待完成對象,但它們不如Windows和Solaris中的端口那麼全面。

+0

何,我犯了一個錯誤。當我說「我將linux代碼移植到使用AF_UNIX地址族進行套接字連接的unix」時,用「windows」替換「unix」:-)無論如何,我也是solaris(和illumos)。所以感謝評論:-)我會看看port_create。 – vtorri 2011-04-02 06:34:14

+0

我會檢查I/O完成端口。有一個服務器在MSDN中使用該方法。實際上,由於框架是事件驅動的,因爲我在Windows上使用select()或WaitForMultipleObjects(),所以我仍然使用該函數。謝謝。 – vtorri 2011-04-02 06:43:45

+0

看來主持人關閉了我的問題,並告訴我閱讀常見問題,看看它爲什麼接近。常見問題解答:「爲什麼有些問題已經結束?被認爲足夠脫離主題的問題可能會被社區關閉」我認爲這並不是理所當然的。在同一篇文章中繼續討論的內容比其他很多內容更具邏輯性,因爲我將不得不重複我之前在這裏所說的內容。這太愚蠢了。此外,在常見問題解答中:「善待別人,以同樣的尊重對待別人,你希望他們對待你」。它似乎不適用於版主。 – vtorri 2011-04-07 18:40:13