詳細說明請見官方文檔html
使用Qt網絡功能須要在pro文件增長網絡庫服務器
建立server對象之後首先要監聽客戶端的鏈接,經過listen函數能夠開啓監聽,須要指定監聽的ip和端口號,ip可以使用QHostAddress::Any網絡
QTcpServer當有新客戶端鏈接時會發出QTcpServer::newConnection的信號,只須要關聯到自定義的槽便可。app
上述爲一個新鏈接到來的槽函數範例,利用nextPendingConnection獲取到新鏈接的socket,存儲此socket,並關聯對應的信號socket
主要有兩個:接收到新數據的信號以及鏈接斷開的信號。函數
當鏈接斷開能夠經過響應信號槽機制實現斷開後的操做。this
客戶端爲主動鏈接方,不須要監聽,直接創建QTcpSocket便可spa
上述例子使用的是信號槽方式等待鏈接成功,也可使用阻塞方式:waitForConnected,等到鏈接成功纔會執行後續代碼,不須要創建新的槽函數。server
經過connectToHost鏈接指定ip和端口,同時將socket的鏈接成功的信號與對應槽鏈接,當鏈接成功能夠將自定義的標記位置爲true,可進行相應的收發。htm
當鏈接成功建議將接收和斷開鏈接的信號進行connect
不管客戶端仍是服務端只有在創建鏈接時有差別,後續的消息收發都相同。
首先經過QTcpSocket::close()能夠主動斷開鏈接,不管客戶端服務端均可以執行主動斷開
經過readyRead()信號能夠在接到信息後進行信息操做,在槽中執行QTcpSocket::readAll()能夠讀取緩衝區全部數據
QTcpSocket::send()可發送信息,調用flush可當即發送緩衝區的數據,不需等待。
Qt同時提供了阻塞收發及鏈接、斷開鏈接的函數:
virtual bool waitForConnected(int msecs = 30000)
virtual bool waitForDisconnected(int msecs = 30000)
virtual bool waitForBytesWritten(int msecs = 30000)
virtual bool waitForReadyRead(int msecs = 30000)
經過上述函數能夠實現阻塞鏈接、斷開鏈接、發送、接收數據內容
網上大部分例子都是單服務器通信,若不作修改鏈接多個客戶端,會出現只有最後一個通信有效的狀況。
主要緣由是在監聽到新鏈接時的處理方式不當:
注意上述代碼在服務端收到信鏈接時會固定的調用一個槽函數,而槽函數每每寫成下述樣式:
m_socket=socket_temp;//記錄此鏈接用於後續數據讀寫
這一行等因而每次有一個新的鏈接都替換了舊的鏈接記錄,天然之友最後一個客戶端鏈接有效,正確的能夠創建list存儲全部鏈接的socket,當收發數據時根據須要指定socket進行收發。這時將disconnected信號進行connect就具備了做用,當某個鏈接斷開時應該從全部鏈接鏈表中刪除此記錄。
由nextPendingConnection建立的QTcpSocket,會有QTcpServer維護,當QTcpServer銷燬是會自動銷燬全部建立的socket,若想提早釋放內容能夠在disconnected信號發生時主動delete
可能考慮到跨平臺問題,Qt使用select實現io多路複用,鏈接數量限制是1024,若須要poll,epoll等可以使用其餘庫,好比libevent
能夠經過setReadBufferSize設置接收緩衝區大小(Qt內部緩衝區大小)
當發送端發送的數據超過buffer大小時會觸發readyread信號,須要注意對此狀況的處理方法,能夠考慮在消息頭增長消息長度
未驗證:Qt有本身內部的緩衝區,消息發送到系統緩衝區,Qt會讀取出來,而調用的Qt函數readall等實際上讀取的是Qt內部緩衝區而非系統緩衝區