Qt 中Socket編程實例
SOCKET socket( int af, int type, int protocol ); 應用程序調(diào)用socket函數(shù)來創(chuàng)建一個能夠進行網(wǎng)絡通信的套接字。第一個參數(shù)指定應用程序使用的通信協(xié)議的協(xié)議族,對于TCP/IP協(xié)議族,該參數(shù)置AF_INET; 第二個參數(shù)指定要創(chuàng)建的套接字類型,流套接字類型為SOCK_STREAM、數(shù)據(jù)報套接字類型為SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不適用某種特定的協(xié)議去封裝它,而是由程序自行處理數(shù)據(jù)報以及協(xié)議首部);第三個參數(shù)指定應用程序所使用的通信協(xié)議。
在LINUX下進行網(wǎng)絡編程,我們可以使用LINUX提供的統(tǒng)一的套接字接口。但是這種方法牽涉到太多的結(jié)構(gòu)體,比如IP地址,端口轉(zhuǎn)換等,不熟練的人往往容易犯這樣那樣的錯誤。QT中提供的SOCKET完全使用了類的封裝機制,使用戶不需要接觸底層的各種結(jié)構(gòu)體操作。而且它采用QT本身的signal-slot機制,使編寫的程序更容易理解。
QT中共提供四個與套按字相關(guān)的類,分別是:
- QServerSocket:TCP-based server
- QSocket: Buffered TCP connection
- QSocketDevice: Platform-independent low-level socket API
- QSocketNotifier: Support for socket callbacks
下面介紹使用QT進行網(wǎng)絡編程,我們使用一個簡單的C/S模式網(wǎng)絡程序說明如何使用QT中的套接字。同時我們用TCP和UDP兩種協(xié)議實現(xiàn)這個程序(該程序客戶端與服務端各向?qū)Ψ桨l(fā)送一個字符口串“abc”)
1、UDP實現(xiàn)
UDP是不連接協(xié)議,沒有客戶端與服務端的概念。
(1)建立套接字相關(guān)對象
- QSocketDevice *MUReceiveSocket; //套接字對象
- QSocketNotifier *MSocketNotifier; //套接字監(jiān)聽對象
(2)初始化套接字相關(guān)對象
- MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram);
- //UDP初始化
- QHostAddress MyAddress;
- QString FakeAddress;
- FakeAddress = get_eth1_ip(); //取得接口IP
- MyAddress.setAddress(FakeAddress);
- MUReceiveSocket->bind(MyAddress,Port);
- //綁定到指定網(wǎng)絡接口地址(IP),指定邏輯端口
- MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,"MSocketNotifier");
- //監(jiān)聽MUReceiveSocket套接字
(3)定義用實現(xiàn)響應slot
- virtual void OnMReceive();
- void Client::OnMReceive(){
- int ByteCount,ReadCount;
- char *IncommingChar;
- fprintf(stderr,"Load a piece of Message!\n");
- ByteCount=MUReceiveSocket->bytesAvailable();
- IncommingChar=(char *)malloc(ByteCount+1);
- ReadCount=MUReceiveSocket->readBlock(IncommingChar,ByteCount);
- IncommingChar[ByteCount]='\0';
- fprintf(stderr,“%s“,IncommingChar); //打印接收的字符串
- }
(4)關(guān)聯(lián)套接字的signal和接收slot
- connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive()));
- //當MSocketNotifier檢測到MUReceiveSocket活躍時調(diào)用OnMReceive
(5)發(fā)送字符串
- char information[20];
- strcpy(information,“abc“);
- MUReceiveSocket->writeBlock(information,length,MyAddress,2201);
2、TCP實現(xiàn)
TCP的實現(xiàn)與UDP的實現(xiàn)大同小異,它是面象連接的協(xié)議。這里只介紹與UDP不同的地方。
服務端:
(1)套接字對象的定義
比UDP多定義一個套接字,一個用來監(jiān)聽端口,一個用來通信。
建立一個QSSocket類繼承QServerSocket
- QSSocket *ServerSocket; //TCP-based server
- QSocketDevice *ClientSocket;
- QSocketNotifier *ClientNotifier;
- QSocketNotifier *ServerNotifier;
(2)套接字的初始化
- QHostAddress MyAddress;
- QString FakeAddress;
- FakeAddress = "127.0.0.1";
- MyAddress.setAddress(FakeAddress);
- UINT Port=1234;
- ServerSocket=new QSSocket(MyAddress,Port,this,0); //指定監(jiān)聽地址及端口
- //這里也可以使用QServerSocket類
- ClientSocket=new QSocketDevice(QSocketDevice::Stream);
- ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,"ClientSocket");
(3)響應連接
只需要在QSSocket的構(gòu)造函數(shù)里添加如下代碼:
- ServerSocket->newConncetion(ClientSocket->socket());
當收到客戶端的連接后,ClientSocket自動響應,并接收數(shù)據(jù)。
(4)接收信息slot與UDP一致,這里不在敘述。
客戶端實現(xiàn):
客戶端的實現(xiàn)與UDP實現(xiàn)大同小異,不同的地方只是客戶端套接字不需要bind端口,因為連接上服務端后TCP會保持這個連接,直到通信的結(jié)束。
小結(jié):對于本篇文章實現(xiàn)Qt 中Socket編程,講解到這,客戶端和服務端的實現(xiàn)很important!實現(xiàn)套接字的網(wǎng)絡通信。希望本文對你有幫助?。?!
【編輯推薦】