2010-12-01 57 views
2

我在與移動電話客戶端通話的Erlang中實現了一個TCP服務器。 手機離線很多,所以服務器必須能夠檢測到它。 因此,我希望服務器通過超時向客戶端發送消息,以便當發生超時 時,連接關閉,客戶端被標記爲脫機。erlang套接字發送超時從未發生

我用這個聽的服務器上的選項:

[{certfile, "cert.pem"}, 
{keyfile, "key.pem"}, 
{reuseaddr, true}, 
{active, false}, 
{send_timeout, 10000}] 

我設置服務器和移動電話之間的連接後,我打開手機,以飛機模式(關閉所有的無線信號)並在服務器上執行ssl:send。發送功能恢復正常,就好像分組已成功發送一樣。

我做錯了什麼?

+0

你從哪裏得到send_timeout?看着`ssl`模塊我看不到那個選項。 – ZeissS 2010-12-01 10:57:00

+0

他從`inet`中得到了。例如,如果使用`ssl:connect/4`,則可以提供任何套接字選項,包括來自`inet`的超時。 – 2010-12-01 15:01:25

回答

2

您是否設置了inet插座上的{send_timeout_close, true}參數?如果沒有,套接字將不會關閉,只是返回一個超時錯誤。也有風險ssl吞下你的錯誤,並與它做一些事情。

的其他一些觀點:

  • 記住檢查的任何ssl:sendssl:receive選項錯誤的返回值。知道發送進行得很好很重要。

    ok = ssl:send(Sock, Data), 
    
  • 底層TCP/IP協議棧實際上可能即使有send_timeout組接受數據,但無法將其作爲另一個端點已關閉。關閉端口的知識首先到達,當堆棧意識到它從來沒有收到ACK時。

  • 插座的入口類型有raw,在inet中定義。它允許您設置特定於操作系統的套接字選項。有可能強制OS在檢測連接丟失方面更積極。

  • 另一種選擇是在ssl:recv/3調用中提示所有事件,其中超時表示設備丟失,而不管其套接字狀態如何。它還具有檢測另一端的應用故障的優點,因爲它不沿着確定的路徑前進。無論如何,您將必須這樣做來處理進一步的請求。

  • 手機客戶端也可以採取行動。如果它通過SSL發送消息並且接收機永遠不會到達(由於飛行模式) - 那麼它知道有什麼地方是錯誤的。但是服務器可能不知道這一點。

  • TCP/IP提供可靠的面向連接的流協議。它沒有防止突然斷開連接。這很重要,因爲您的協議必須本身處理斷開連接問題。如果您的協議有某種確認或確認,這一點尤其重要。