我是新來的套接字,並嘗試通過TCP套接字創建連接池。我的實現發送32位長度,然後爲每個呼叫發送二進制消息。但我有時遇到問題,有時讀者從服務器接收以前的響應(可能發生在客戶端關閉並在發送錯誤時重新建立套接字)。如何在新請求之前刷新套接字(前一個調用的剩餘字節)。任何建議?TCP連接池
編輯:我知道tcp總是流0,如果我發送消息之前的字節(1),所以我可以有一個刷新函數來檢查新的調用之前,套接字不是空的。
我是新來的套接字,並嘗試通過TCP套接字創建連接池。我的實現發送32位長度,然後爲每個呼叫發送二進制消息。但我有時遇到問題,有時讀者從服務器接收以前的響應(可能發生在客戶端關閉並在發送錯誤時重新建立套接字)。如何在新請求之前刷新套接字(前一個調用的剩餘字節)。任何建議?TCP連接池
編輯:我知道tcp總是流0,如果我發送消息之前的字節(1),所以我可以有一個刷新函數來檢查新的調用之前,套接字不是空的。
文章實際問幾個問題:
這些實際上是兩回事。連接池只是管理一組連接的一種方式。實現一個簡單的方法是使用一類如:
package netpool
import (
"net"
)
const MaxConnections = 3
type Error string
func (e Error) Error() string {
return string(e)
}
var ErrMaxConn = Error("Maximum connections reached")
type Netpool struct {
name string
conns int
free []net.Conn
}
func NewNetpool(name string) *Netpool {
return &Netpool{
name: name,
}
}
func (n *Netpool) Open() (conn net.Conn, err error) {
if n.conns >= MaxConnections && len(n.free) == 0 {
return nil, ErrMaxConn
}
if len(n.free) > 0 {
// return the first free connection in the pool
conn = n.free[0]
n.free = n.free[1:]
} else {
addr, err := net.ResolveTCPAddr("tcp", n.name)
if err != nil {
return nil, err
}
conn, err = net.DialTCP("tcp", nil, addr)
if err != nil {
return nil, err
}
n.conns += 1
}
return conn, err
}
func (n *Netpool) Close(conn net.Conn) error {
n.free = append(n.free, conn)
return nil
}
我創建了一個獨立的類在這裏。它通常會作爲MyHTTPHost或MyDatabase等更高級別類的一部分來實現。
在這個簡單的實現中,不會跟蹤通過netpool.Open()返回的連接。可以通過調用Open()來泄漏連接,然後關閉netpool.Close()之外的連接。例如,如果要保存活動和非活動池,可以跟蹤它們,這可以解決此問題。
一對夫婦的其他東西,你可能要添加到池的實現:
一旦你有一個連接,你可以調用正常讀寫就可以了。要清除套接字上的所有未完成數據,只需使用ioutil.ReadAll()輔助函數即可。默認情況下,如果沒有可用的數據,它將無限期地阻塞。爲了避免這種情況,使用添加讀取超時:
conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
_, err = ioutil.ReadAll(conn)
neterr, ok := err.(net.Error)
if ok && neterr.Timeout() {
err = nil // timeout isn't an error in this case
}
if err != nil {
// handle the error case.
}
如果有正在等待這將從給定的連接讀取所有數據,如果沒有數據待處理500毫秒後,將返回一個I/O超時錯誤。
類型聲明是必需的,因爲ioutil.ReadAll()返回一個Error接口,而不是一個net.Error接口,我們需要後者能夠輕鬆地找出是否由於超時而返回調用。
只是一個想法...或者open()需要MaxConnections(1)類型的實際最大連接數和一個最大連接池數;或者(2)刪除頂部的if並允許儘可能多的連接,只有在池滿後才能正確關閉它們。 – Richard 2015-04-08 12:12:32
歡迎來到SO!如果你能顯示一些你的代碼,那將是非常棒的。 – vyegorov 2012-04-25 19:20:38