Indy:Connection Closed Gracefully

以下內容轉自http://blog.163.com/liang_liu99/blog/static/88415216200811171470848/

 Many Indy users are annoyed by the EIdConnClosedGracefully exception that is raised with Indy servers, especially the HTTP and other servers. EIdConnClosedGracefully is an exception signaling that the connection has been closed by the other side intentionally. This is not the same as a broken connection which would cause a connection reset error. If the other side has closed the connection and the socket is read or written to, EIdConnClosedGracefully will be raised by Indy. This is similar to attempting to read or write to a file that has been closed without your knowledge.
    很多Indy組件的用戶常常因爲 Indy server 拋出的EIdConnClosedGracefully 異常而煩惱,特別是 HTTP 和其他的server。EIdConnClosedGracefully 是連接已經被另一方故意的關閉的象徵。這與導致連接復位的錯誤所致的斷開的連接不同。如果另一方已經關閉了連接,並且仍然向套接字中讀寫,Indy組件將會拋出EIdConnClosedGracefully異常。這與您嘗試向一個在您不知情的情況下被關閉的文件中讀寫數據是很相似的。

    In some cases this is a true exception and your code needs to handle it. In other cases (typically servers) this is a normal part of the functioning of the protocol and Indy handles this exception for you. Even though Indy catches it, when running in the IDE the debugger will be triggered first. You can simply press F9 to continue and Indy will handle the exception, but the constant stopping during debugging can be quite annoying. In the cases where Indy catches the exception, your users will never see an exception in your program unless it is run from the IDE.
    在有些情況下這是一個真的異常,你需要編程處理它。在另外一些情況下(典型的服務器),這是協議功能的正常的一部分,Indy組件會爲您處理這個異常。即使Indy組件捕捉到了這個異常,當在IDE編程環境中運行時,調試器也將會首先觸發它。你只要按F9鍵繼續運行,Indy組件將會處理這個異常,但是在調試期間不斷的停止運行是非常煩人的。在Indy組件捕捉到這個異常的情況下,除非在IDE中運行,否則您的用戶將不會再看到異常提示。

    Simple solution
    簡單的解決方法

    Because the EIdConnClosedGracefully is a common exception especially with certain servers it descends from EIdSilentException. On the Language Exceptions tab of Debugger Options (Tools Menu) you can add EIdSilentException to the list of exceptions to ignore. After this is added the exceptions will still occur in the code and be handled, but the debugger will not stop the program to debug them.
    因爲對於從EIdSilentException繼承來的服務器,EIdConnClosedGracefully是一個正常的異常。您可以在“Tools”菜單的“Debugger Options”的“Language Exceptions”選項卡中將EIdSilentException加到忽略的異常的列表中。當加到忽略的異常的列表中後這個異常仍然會在代碼中觸發並被處理,但是調試器將不會停止程序的運行。

    Is it an error?
    這是一個錯誤嗎?

    All exceptions are not errors. Many developers have been taught or assumed that all exceptions are errors. However this is not the case, and this is why they are called exceptions and not errors.
    異常不一定是錯誤。很多開發者都認爲所有的異常都是錯誤。但是事實不是這樣的,這就是爲什麼之所以叫異常而不叫錯誤的原因。

    Exceptions are exactly that - exceptions. Delphi and C++ Builder use exceptions to handle errors in an elegant way. However exceptions have other uses besides errors as well. EAbort is one example of an exception that is not necessarily an error. Exceptions such as these are used to modify standard program flow and communicate information to a higher calling level where they are trapped. Indy uses exceptions in such a way as well.
    異常就是異常。Delphi 和 C++ Builder 使用異常處理錯誤。但是異常有錯誤之外的其他用途。EAbort是一個異常不一定是錯誤的例子。這樣的異常用來將標準的程序流程和交流信息調整到一個更高的能被捕捉到的層次。Indy組件也是這樣使用異常的。

    Why is it an exception?
    它爲什麼是一個異常?

    Many users have commented that maybe it there should be a return value to signal this condition instead of an exception. However this is the wrong approach in this case.
    許多用戶說它應該返回一個信號而不是一個異常。但是在這種情況下這是一個錯誤的方式。

    The EIdConnClosedGracefully is raised from a core routine, however when this routine is called it is normally several method calls deep. The EIdConnClosedGracefully is in fact an exception and needs to be trapped by the topmost caller in most cases. The proper way to handle this is an exception.
    EIdConnClosedGracefully異常從核心循環拋出,但是當這個循環被調用時,有幾種在深層調用的方法。 EIdConnClosedGracefully實際上是一個異常,並且在很多情況下需要被頂層調用者捕捉。處理它的正確的方法是捕獲異常。

    When is it an error?
    什麼時候它是一個錯誤呢?

    When EIdConnClosedGracefully is raised in a client, it is an error and you should trap and handle this exception.
    當客戶端拋出一個EIdConnClosedGracefully時,它就是一個錯誤,您就應當捕捉並且處理這個異常。

    In servers it is an exception. However sometimes it is an error, and sometimes it is an exception. For many protocols this exception is part of the normal functioning of the protocol. Because of this common behavior, if you do not catch the EIdConnClosedGracefully in your server code, Indy will. It will then mark the connection as closed and stop the thread assigned to the connection. If you wish to handle this exception yourself you may, otherwise Indy will handle it and take the appropriate actions for you automatically.
    在服務器中它是一個異常。但是在有些情況下這是一個錯誤,有些情況下是異常。對於很多協議,這個異常是協議正常功能的一部分。因爲這個,如果您在你的服務器代碼中沒有捕捉EIdConnClosedGracefully,Indy 組件將會捕獲它。它將會將這個連接標記爲關閉,並且會停止有關這個連接的所有線程。您可以以您自己的方式處理這個異常,否則的話 Indy 組件將會處理這個異常並且爲您實現正確的處理。

    Why does this exception occur in servers?
    爲什麼這個異常會在服務器中觸發?

    When a client is connected to a server there are two common ways to handle the disconnection:
    當一個客戶端連接到服務器上時,有兩種常用的方式處理這個斷開的連接:

    Mutual Agreement - Both sides agree to mutually disconnect by one side signaling (and the other optionally acknowledging) and then both sides disconnecting explicitly.
    Single Disconnect - Disconnect and let the remote side take notice.
    With the Mutual Agreement method both sides know when to disconnect and both explicitly disconnect. Most conversational protocols such as Mail, News, etc disconnect in this manner. When the client is ready to disconnect it sends a command to the server telling it that it will disconnect. The server replies with an acknowledgement of the disconnect request, and then both the client and server disconnect. In these cases an EIdConnClosedGracefully should not be raised, and if one occurs it is in fact an error and should be handled.
    協商方式-雙方都通過信號同意另一方的連接斷開,並且雙方都會明確的斷開連接。大多數會話協議(例如Mail,News等)都是以這種方式斷開連接。當客戶端準備斷開連接時,它將向服務器發出一個請求告訴服務器它將斷開連接。服務器會返回一個同意斷開連接的確認信號,然後客戶端和服務器都將斷開連接。在這種情況下,EIdConnClosedGracefully不應該被觸發,如果被觸發了,那麼它就確實是一個錯誤,您必須處理它。

    In some cases of Mutual Disconnect no command will be issued, but both sides know when the other will disconnect. Often a client will connect, issue one command, receive the response from the server and disconnect. While no explicit command was issued by the client, the protocol states that the connection should be disconnected after one command and response. Some of the time protocols are examples of this.
    在有的協商方式中,不會發出這樣的請求,但是雙方都知道對方何時斷開連接。一般的,客戶端連接、發出一個請求,然後收到從服務器返回的消息。當客戶端沒有發出明確的請求時,協議規定:當請求和迴應後連接必須被斷開。一些時間協議就是這樣的例子。

    With Single Disconnect, one side just disconnects. The other side is left to detect this and then take appropriate action to terminate the session. With protocols that use this disconnection method you will see EIdConnClosedGracefully and it is normal. It is an exception, but Indy knows about it and will handle it for you. The whois protocol is an example of this. The client connects to the server and sends a string containing the domain to query. The server then sends the response and disconnects when the response is finished. No other signal is sent to the client other than a normal disconnection that the response is finished.
    單方斷開連接方式-一方自主的斷開連接。另一方稍後會檢測到並且會採取一定的措施來終止這個會話。使用這樣連接斷開策略的協議將會引發EIdConnClosedGracefully異常,這是正常的。它是一個異常,但是Indy組件將會爲您處理它。whois就是一個典型的例子。客戶端連接到服務器並且發送一個包含自己域名的字符串到服務器隊列中。服務器會迴應並且在迴應完畢後斷開連接。除了迴應導致的正常的連接斷開外,沒有任何信號發送給客戶端。

    The HTTP allows for both Mutual Agreement and Single Disconnect and this is why it is common to see the EIdConnClosedGracefully with the HTTP server. HTTP 1.0 works similar to the whois protocol in that the server signals the client simply by disconnecting after the request has been served. The client then must use new connections for each request.
    HTTP協議允許上述兩種方式(協商方式、單方斷開連接方式),這就是爲什麼在HTTP服務器中經常可以見到EIdConnClosedGracefully異常的原因。HTTP 1.0協議和whois都是在請求被處理後由服務端斷開連接。客戶端必須在每次請求數據時都要建立新的連接。

    HTTP 1.1 allows a single connection to request multiple documents. However there is no command to signal a disconnect. At any time, either the client or the server can disconnect after a response. When the client disconnects but the server is still accepting requests, a EIdConnClosedGracefully will be raised. In most cases in HTTP 1.1, the client is the one that disconnects. A server will disconnect when it implements part of HTTP 1.1, but does not support the keep alive option.
    HTTP 1.1允許使用一個連接獲取多個文件。但是沒有斷開連接的命令。當客戶端已經斷開,但是服務端仍然接受請求時,EIdConnClosedGracefully異常就會被觸發。對於HTTP 1.1,大部分情況下都是客戶端斷開連接。如果服務器聲明瞭HTTP 1.1,那麼它將會斷開連接,但是不支持保持連接的選項。

發佈了53 篇原創文章 · 獲贊 15 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章