linux网络通信移植,基于socket API的C/S通信:将Qt程序从Linux移植到windows
Qt是一個(gè)跨平臺(tái)的GUI開(kāi)發(fā)語(yǔ)言,它是對(duì)C++在圖形設(shè)計(jì)方面上的一種擴(kuò)充。Qt本身包含一系列用來(lái)設(shè)計(jì)圖形界面的類,并且對(duì)C++原有的類都進(jìn)行了再次封裝。如果你的程序采用Qt的類庫(kù),那么源程序在不同平臺(tái)重新編譯即可;如果程序中使用某些C++或C庫(kù)函數(shù),那么在移植時(shí)就需要針對(duì)不同平臺(tái)作一些改動(dòng)。
本文所舉例的移植代碼是基于socket API的C/S模型的客戶端,該客戶端的原始代碼在linux系統(tǒng)下完成(以下稱為“源代碼”),現(xiàn)在要將其移植到windows平臺(tái)下(以下稱“移植代碼”)。源代碼的界面部分采用Qt完成,而通信部分則是采用原始的socket接口。
1.加入動(dòng)態(tài)庫(kù)
在linux系統(tǒng)中,socket API屬于libc庫(kù),因此只需在程序中加頭文件即可。而在windows系統(tǒng)下,由于socket接口是繼承Unix系統(tǒng)而來(lái),因此需要加入wsock32庫(kù),并且加上相應(yīng)的頭文件winsock2.h。加入該庫(kù)具體的做法是在工程問(wèn)價(jià)中加入下面的語(yǔ)句:
LIBS += -lwsock32
2.初始化套接字庫(kù)
在windows下有兩套socket API,一種是經(jīng)過(guò)C++封裝的csocket類,而另一種則是原始的socket接口,為了降低移植的復(fù)雜性,我們采用后者。
在將wsock32動(dòng)態(tài)庫(kù)加入移植程序后,socket接口還不能使用,因?yàn)樵谶@之前必須使用WSAStartup函數(shù)對(duì)該庫(kù)進(jìn)行初始化。具體的初始化代碼可以參考如下:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return;
}
if ( LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1 ) {
WSACleanup();
return;
WSAStartup函數(shù)有兩個(gè)參數(shù),wVersionRequested用來(lái)向該函數(shù)傳遞socket接口調(diào)用者可以使用socket的最高版本號(hào),通過(guò)MAKEWORD宏即可完成版本號(hào)的組裝,該變量的低字節(jié)指定主版本號(hào)而低字節(jié)指定次版本號(hào)。wsaData用來(lái)接收socket函數(shù)執(zhí)行期間的一些數(shù)據(jù)。
當(dāng)WSAStartup函數(shù)初始化動(dòng)態(tài)庫(kù)成功時(shí)返回0,否則返回-1。
當(dāng)初始化成功后,還要再確認(rèn)已加載的動(dòng)態(tài)庫(kù)的版本是否和我們所指定的動(dòng)態(tài)庫(kù)版本相吻合,如果不符合,則通過(guò)WSACleanup函數(shù)清除已加載的動(dòng)態(tài)庫(kù)。
動(dòng)態(tài)庫(kù)加載成功后,接下來(lái)就可以使用socket接口函數(shù)了,當(dāng)使用完畢時(shí),需要用WSACleanup函數(shù)卸載動(dòng)態(tài)庫(kù)。
3.更改套接字描述符
在使用一系列socket接口之前,必須使用socket函數(shù)創(chuàng)建套接字。在linux下,原始的socket函數(shù)返回的套接字描述符是整型,但是在windows下,該函數(shù)返回的套接字描述符是SOCKET類型。因此源代碼和移植代碼參考如下:
源代碼:
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
ui->statusLabel->setText("ERROR:socket connceting fail!");
exit(1);
}
移植代碼:
SOCKET sockfd;
if ((cli.sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
ui->statusLabel->setText("ERROR:socket connceting fail!");
exit(1);
}
既然在移植代碼中套接字描述符不是整型,那么其錯(cuò)誤返回值也應(yīng)該不是-1而是標(biāo)準(zhǔn)的錯(cuò)誤返回值INVALID_SOCKET。
4.close函數(shù)
源代碼中關(guān)閉套接字選用close(),而移植程序相應(yīng)的使用closesocket()。并且此時(shí)用WSACleanup()關(guān)閉已加載的動(dòng)態(tài)庫(kù)。
進(jìn)過(guò)上述幾個(gè)部分的修改,此時(shí)移植程序在windows下即可編譯成功。
總結(jié)
以上是生活随笔為你收集整理的linux网络通信移植,基于socket API的C/S通信:将Qt程序从Linux移植到windows的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: jmeter参数值只读取了第一个_基础入
- 下一篇: linux数组长度的函数,linux a