2016-11-29 41 views
2

我确实有一个进程从第二本地进程接收数据。我需要测试连接错误是否处理得当,以及连接错误是否自动重新连接并在断开连接后继续接收数据。如何在GO中测试TCP断开

为此,我试图使它突然断开或将TCP连接置于单元测试的错误状态。 如在this question中看到的,以检查连接是否已关闭,我正在检查数据来测试它是否返回错误。 我不知道如何:

  • 关闭连接非正常
  • 使其处于错误状态

这是我的数据接收器的本质:

import (
     "bufio" 
     "encoding/json" 
     "fmt" 
     "io" 
     "net" 
    ) 

    type Message struct { 
     ID string `json:"id"` 
    } 

    func ReceiveData(listener Listener) { 
     var tcpConn net.Conn 
     var addr string = "127.0.0.1:9999" 
     tcpConn, err := net.Dial("tcp", addr) 
     socketReader := bufio.NewReader(tcpConn) 
     decoder := json.NewDecoder(socketReader) 

     for { 
      var msg Message 
      if err := decoder.Decode(&msg); err == io.EOF { 
       listener.ProcessUpdate(Message{}, fmt.Errorf("Received EOF"), nil) 
       tcpConn = nil 
       return 
      } else if err != nil { 
       listener.ProcessUpdate(Message{}, nil, fmt.Errorf("Error decoding message: %s", err.Error())) 
       tcpConn = nil 
       return 
     } 

     // process message 
     _ = msg 

     // Test disconnection 
     // This does not disconnect: 
     // tcpConn = nil 
     // This does but gracefully: 
     // tcpConn.Close() 
    } 

我不想嘲笑TCP连接,因为我想试试真正的数据生产者。如果需要,我会看看它。

+0

究竟什么叫收盘意思连接“非常”? – JimB

+0

意外断开,人们拔掉电缆,另一端断电,tcp信息格式不正确。我怀疑大多数这些会产生超时,我不知道'tcpConn.Read()'可能产生的所有错误。 –

+0

如果您希望远程端模拟断开连接,如拉动电缆或断开电源,请确保Keepalive被禁用并停止响应。如果您想以其他各种方式断开连接,则需要在网络的较低级别执行此操作。 – JimB

回答

1

一种解决方案是一个deadline设置为TCP连接本身:

tcpConn.SetDeadline(time.Now()) 

后来这将触发超时错误,可以被捕获:

err := decoder.Decode(&msg); 
if err != nil { 
    if neterr, ok := err.(net.Error); ok && neterr.Timeout() { 
     fmt.Errorf("TCP timeout : %s", err.Error()) 
    } else { 
     fmt.Errorf("Received error decoding message: %s", err.Error()) 
    } 
}