国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

簡(jiǎn)析Windows C語(yǔ)言網(wǎng)絡(luò)編程技術(shù)與方法

2011-04-03 04:52:25韓玉坤邵國(guó)強(qiáng)
關(guān)鍵詞:網(wǎng)絡(luò)應(yīng)用描述符服務(wù)器端

韓玉坤,邵國(guó)強(qiáng),楊 紅

(大慶師范學(xué)院 計(jì)算機(jī)科學(xué)與信息技術(shù)學(xué)院,大慶 黑龍江 163712)

0 引言

網(wǎng)絡(luò)程序是對(duì)速度要求高、對(duì)硬件操作較多的程序,利用Windows C編程方式編寫的程序源代碼量雖然較大,但可執(zhí)行代碼效率高,大多數(shù)網(wǎng)絡(luò)應(yīng)用程序是用Windows C編程方式開發(fā)的。用Windows C進(jìn)行網(wǎng)絡(luò)應(yīng)用編程,最核心的內(nèi)容就是使用套接字(socket)函數(shù)。

1 套接字(socket)概念

1.1 套接字

套接字是支持TCP/IP網(wǎng)絡(luò)通信的基本操作單元。可以將套接字看作是不同主機(jī)間的進(jìn)程進(jìn)行雙向通信的端點(diǎn),在一個(gè)雙方可以通信的套接字實(shí)例中,既保存了本機(jī)的IP地址和端口,也保存了對(duì)方的通信采用的協(xié)議等信息。應(yīng)用程序在使用TCP/IP協(xié)議進(jìn)行通信之前,必須向操作系統(tǒng)申請(qǐng)創(chuàng)建一個(gè)套接字用于通信。如果申請(qǐng)成功,系統(tǒng)返回一個(gè)短整型數(shù)作為描述符,以標(biāo)識(shí)該socket。應(yīng)用程序在調(diào)用函數(shù)進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸時(shí),就將這個(gè)socket描述符作為參數(shù),而不必在每次傳輸數(shù)據(jù)時(shí)都指明遠(yuǎn)程目標(biāo)細(xì)節(jié)。

1.2 Winsock

為了方便網(wǎng)絡(luò)編程,Microsoft在90年代初,聯(lián)合了其他幾家公司共同制定的一套WINDOWS下的網(wǎng)絡(luò)編程接口Winsock,它是通過(guò)C語(yǔ)言的動(dòng)態(tài)鏈接庫(kù)方式提供的,主要由winsock.h頭文件和動(dòng)態(tài)鏈接庫(kù)winsock.dll組成。用Visual C++6.0編譯Windows C程序,使用Winsock API函數(shù)時(shí),首先要把wsock32.lib添加到它的庫(kù)模塊中。添加的方法有兩種:①直接添加到庫(kù)模塊中,步驟:工程-設(shè)置-link選項(xiàng)卡-在對(duì)象/庫(kù)模塊文本框中添加wsock32.lib;②用預(yù)處理命令:#pragma comment(lib,”wsock32.lib”)。

1.3 套接字工作原理

要通過(guò)互聯(lián)網(wǎng)進(jìn)行通信,至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶機(jī)端,稱之為ClientSocket;另一個(gè)運(yùn)行于服務(wù)器端,稱之為ServerSocket。根據(jù)連接啟動(dòng)的方式以及本地套接字要連接的目標(biāo),套接字之間的連接過(guò)程可以分為三個(gè)步驟:服務(wù)器監(jiān)聽,客戶端請(qǐng)求,連接確認(rèn)。

所謂服務(wù)器監(jiān)聽,指服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),所謂客戶端請(qǐng)求,指由客戶端的套接字提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶端的套接字指出服務(wù)器端套接字的地址和端口號(hào),然后向服務(wù)器端套接字提出連接請(qǐng)求;所謂連接確認(rèn),指當(dāng)服務(wù)器端套接字監(jiān)聽到或者說(shuō)接收到客戶端套接字的連接請(qǐng)求,就響應(yīng)客戶端套接字的請(qǐng)求,連接就建立好了。

2 Windows下Socket函數(shù)的使用

在Windows下進(jìn)行網(wǎng)絡(luò)編程主要使用Winsock提供的API函數(shù)。

1)初始化DLL庫(kù)WSAStartup()函數(shù)和釋放DLL庫(kù)WSAClenaup()函數(shù)。不管是客戶端還是服務(wù)器,開發(fā)Windows C網(wǎng)絡(luò)應(yīng)用程序時(shí),必須先用WSAStartup()函數(shù)加載Winsock動(dòng)態(tài)庫(kù)(DLL)。只有該函數(shù)在調(diào)用成功之后才能使用其它的Winsock網(wǎng)絡(luò)操作函數(shù)。函數(shù)原型為:int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData),其中,參數(shù)WVersionRequired:<輸入>表示欲使用的Winsock版本,這是一個(gè)WORD類型的整數(shù),它的高位字節(jié)定義的是次版本號(hào),低位字節(jié)定義的是主版本號(hào)。參數(shù)LpWSAData:<輸出>是一個(gè)指向WSADATA資料的指針。當(dāng)Windows C網(wǎng)絡(luò)程序在完成對(duì)請(qǐng)求的Winsock庫(kù)的使用后,要調(diào)用WSACleanup函數(shù)來(lái)解除與Winsock庫(kù)的綁定并且釋放Winsock庫(kù)所占用的系統(tǒng)資源。

2)創(chuàng)建套接字socket()和關(guān)閉套接字closesocket()函數(shù)。應(yīng)用程序在使用套接字前,首先必須擁有一個(gè)套接字,系統(tǒng)調(diào)用socket()向應(yīng)用程序提供創(chuàng)建套接字的手段。函數(shù)原型為:SOCKET PASCAL FAR socket(int af, int type, int protocol),其中,參數(shù)af指定通信發(fā)生的區(qū)域,Windows中用AF_INET;參數(shù)type 描述要建立的套接字的類型;參數(shù)protocol說(shuō)明該套接字使用的特定協(xié)議,如果不希望特別指定使用的協(xié)議,即使用默認(rèn)的連接模式,closesocket()關(guān)閉套接字s,并釋放分配給該套接字的資源;如果s涉及一個(gè)打開的TCP連接,則該連接被釋放。closesocket()的調(diào)用格式為:BOOL PASCAL FAR closesocket(SOCKET s),其中,參數(shù)s為待關(guān)閉的套接字描述符。如果沒有錯(cuò)誤發(fā)生,closesocket()返回0;否則返回值SOCKET_ERROR。

3)指定本地地址bind()。bind()將套接字地址(包括本地主機(jī)地址和本地端口地址)與所創(chuàng)建的套接字號(hào)聯(lián)系起來(lái),即將名字賦予套接字,以指定本地半相關(guān)。函數(shù)原型為:int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR *name, int namelen),其中,參數(shù)s是由socket()調(diào)用返回的,并且作為連接的套接字描述符(套接字號(hào));參數(shù)name 是賦予給套接字s的本地地址(名字),其長(zhǎng)度可變,結(jié)構(gòu)隨通信域的不同而不同;namelen表明了name的長(zhǎng)度。如果沒有錯(cuò)誤發(fā)生,bind()返回0;否則返回值SOCKET_ERROR。

4)監(jiān)聽連接listen()、建立套接字連接accept()和connect()函數(shù)。listen()用于服務(wù)器,表明它愿意接收連接。listen()需在accept()之前調(diào)用,其調(diào)用格式為:int PASCAL FAR listen(SOCKET s, int backlog),其中,參數(shù)s標(biāo)識(shí)一個(gè)本地已建立、尚未連接的套接字號(hào),服務(wù)器從它上面接收請(qǐng)求。backlog表示請(qǐng)求連接隊(duì)列的最大長(zhǎng)度,用于限制排隊(duì)請(qǐng)求的個(gè)數(shù)。如果沒有錯(cuò)誤發(fā)生,listen()返回0;否則返回SOCKET_ERROR。

accept()和connect()這兩個(gè)函數(shù)用于完成一個(gè)完整相關(guān)的建立。accept()用于服務(wù)器,在調(diào)用過(guò)listen ()之后,它使服務(wù)器等待來(lái)自某客戶進(jìn)程的實(shí)際連接。函數(shù)原型為:SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR*addr, int FAR*addrlen),其中,參數(shù)s為本地套接字描述符;addr 指向客戶端套接字地址結(jié)構(gòu)的指針,用來(lái)接收連接實(shí)體的地址,addr的格式由套接字創(chuàng)建時(shí)建立的地址族決定;addrlen 為客戶端套接字地址的長(zhǎng)度(字節(jié)數(shù))。如果沒有錯(cuò)誤發(fā)生,accept()返回一個(gè)SOCKET類型的值,表示接收到的套接字的描述符,否則返回值INVALID_SOCKET。

connect()用于客戶端,它使客戶端與服務(wù)器之間建立連接。函數(shù)原型為:int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR*name, int namelen)。其中,參數(shù)s是欲建立連接的本地套接字描述符;參數(shù)name說(shuō)明對(duì)方套接字地址結(jié)構(gòu)的指針;對(duì)方套接字地址長(zhǎng)度由namelen說(shuō)明。如果沒有錯(cuò)誤發(fā)生,connect()返回0,否則返回值SOCKET_ERROR。

5)數(shù)據(jù)傳輸send()和recv()。當(dāng)一個(gè)連接建立以后,就可以傳輸數(shù)據(jù)了。常用的系統(tǒng)調(diào)用函數(shù)有send()和recv()。send()調(diào)用用于參數(shù)s指定的已連接的數(shù)據(jù)包或流套接字上發(fā)送輸出數(shù)據(jù),格式為int PASCAL FAR send(SOCKET s, const char FAR*buf, int len, int flags),其中,參數(shù)s為已連接的本地套接字描述符;buf 指向存有發(fā)送數(shù)據(jù)的緩沖區(qū)的指針,其長(zhǎng)度由len 指定;flags 指定傳輸控制方式。如果沒有錯(cuò)誤發(fā)生,send()返回所有發(fā)送的字節(jié)數(shù);否則返回SOCKET_ERROR。recv()調(diào)用用于參數(shù)s指定的已連接的數(shù)據(jù)包或流套接字上接收輸入數(shù)據(jù),格式為:int PASCAL FAR recv(SOCKET s, char FAR*buf, int len, int flags),其中,參數(shù)s 為已連接的套接字描述符;buf指向接收輸入數(shù)據(jù)緩沖區(qū)的指針,其長(zhǎng)度由len 指定;flags 指定傳輸控制方式。如果沒有錯(cuò)誤發(fā)生,recv()返回所有接收的字節(jié)數(shù);如果連接被關(guān)閉,返回0;否則返回SOCKET_ERROR。

6)輸入/輸出多路復(fù)用select()。select()調(diào)用用于檢測(cè)一個(gè)或多個(gè)套接字的狀態(tài)。對(duì)每一個(gè)套接字來(lái)說(shuō),該調(diào)用可以請(qǐng)求讀、寫或錯(cuò)誤狀態(tài)方面的信息。請(qǐng)求給定狀態(tài)的套接字集合由fd_set結(jié)構(gòu)指示。在返回時(shí),此結(jié)構(gòu)被更新,以反映那些滿足特定條件的套接字的子集。同時(shí),select()調(diào)用返回滿足條件的套接字的數(shù)目,其調(diào)用格式為:int PASCAL FAR select(int nfds, fd_set FAR*readfds, fd_set FAR*writefds,{fd_set} FAR*exceptfds, const struct timeval FAR*timeout),其中,參數(shù)nfds指明被檢查的套接字描述符的值域,此變量一般被忽略;參數(shù)readfds指向要進(jìn)行讀檢測(cè)的套接字描述符集合的指針,調(diào)用者希望從中讀取數(shù)據(jù),參數(shù)writefds 指向要進(jìn)行寫檢測(cè)的套接字描述符集合的指針;exceptfds指向要檢測(cè)是否出錯(cuò)的套接字描述符集合的指針;timeout指向select()函數(shù)等待的最大時(shí)間,如果設(shè)為NULL則為阻塞操作。select()返回包含在fd_set結(jié)構(gòu)中已準(zhǔn)備好的套接字描述符的總數(shù)目,若發(fā)生錯(cuò)誤則返回SOCKET_ERROR。

3 Windows C網(wǎng)絡(luò)編程實(shí)例

為了更直觀說(shuō)明C/S模式下的通信,下面給出一個(gè)面向TCP協(xié)議簡(jiǎn)單的控制臺(tái)網(wǎng)絡(luò)應(yīng)用程序?qū)嵗?/p>

實(shí)例:當(dāng)服務(wù)器端程序啟動(dòng)后,服務(wù)器端馬上進(jìn)入偵聽狀態(tài),這時(shí)當(dāng)客戶端程序啟動(dòng)后,客戶端立即與服務(wù)器建立了連接。此時(shí),客戶端就可與服務(wù)器進(jìn)行通信了。當(dāng)一端發(fā)送出”bye”信息時(shí)結(jié)束通信。

//服務(wù)器端Server.cpp

#include

#include

#include

#pragma comment(lib,"ws2_32.lib")

#define PORT 3333

int main()

{WSADATA wsa;

if(WSAStartup(MAKEWORD(2,2),&wsa) != 0)//初始化套接字DLL

{printf("套接字初始化失敗! ");return(-1); }

SOCKET serverSock;

//創(chuàng)建套接字

if((serverSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)

{printf("創(chuàng)建套接字失敗! "); return(-1);}

struct sockaddr_in sserverAddr;

memset(&sserverAddr,0,sizeof(sockaddr_in));

sserverAddr.sin_family = AF_INET;

sserverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

sserverAddr.sin_port = htons(PORT);

}

4 結(jié)束語(yǔ)

網(wǎng)絡(luò)應(yīng)用編程是近年來(lái)非常流行的編程技術(shù),它不僅要求具備熟練的編程功底,而且還要求有堅(jiān)實(shí)的網(wǎng)絡(luò)知識(shí)基礎(chǔ),在程序設(shè)計(jì)思路上也與傳統(tǒng)編程不同。通過(guò)文中給出的簡(jiǎn)單實(shí)例,能夠得出用Windows C編寫網(wǎng)絡(luò)應(yīng)用程序的一個(gè)模式。因此,掌握網(wǎng)絡(luò)編程技術(shù),就要深入研究和熟練掌握Windows下的 Socket函數(shù)的用法,才能更好地進(jìn)行網(wǎng)絡(luò)應(yīng)用程序的開發(fā)。

[參考文獻(xiàn)]

[1] 王艷平.Windows網(wǎng)絡(luò)與通信程序設(shè)計(jì)[M].北京:人民郵電出版社,2009.

[2] 侯俊杰.深入淺出Visual C++ 6程序設(shè)計(jì)導(dǎo)學(xué)[M].北京:清華大學(xué)出版社,2002.

猜你喜歡
網(wǎng)絡(luò)應(yīng)用描述符服務(wù)器端
基于結(jié)構(gòu)信息的異源遙感圖像局部特征描述符研究
交通領(lǐng)域中面向D2D的5G通信網(wǎng)絡(luò)應(yīng)用探析
基于數(shù)字電子技術(shù)的通信網(wǎng)絡(luò)應(yīng)用研究
Linux單線程并發(fā)服務(wù)器探索
淺析異步通信層的架構(gòu)在ASP.NET 程序中的應(yīng)用
成功(2018年10期)2018-03-26 02:56:14
利用CNN的無(wú)人機(jī)遙感影像特征描述符學(xué)習(xí)
大氣環(huán)境質(zhì)量評(píng)價(jià)工作中基于MATLAB的BP神經(jīng)網(wǎng)絡(luò)應(yīng)用探究
電子制作(2016年11期)2016-11-07 08:43:38
在Windows中安裝OpenVPN
新媒體視閾下青少年網(wǎng)絡(luò)應(yīng)用行為探析
聲屏世界(2015年5期)2015-02-28 15:19:45
網(wǎng)頁(yè)防篡改中分布式文件同步復(fù)制系統(tǒng)
东莞市| 忻州市| 乐东| 拜城县| 浏阳市| 晋州市| 龙井市| 永德县| 肇源县| 江门市| 达孜县| 晋州市| 泉州市| 蒙阴县| 元谋县| 玉门市| 宣化县| 界首市| 汤原县| 涞源县| 冀州市| 凉山| 丹棱县| 民勤县| 大姚县| 寻乌县| 南开区| 楚雄市| 远安县| 游戏| 始兴县| 花莲市| 延吉市| 合山市| 江孜县| 内丘县| 内黄县| 什邡市| 巴南区| 龙门县| 邹平县|