




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、北京交通大學(xué)出版社北京交通大學(xué)出版社 基于基于TCP(UDP) 的的 網(wǎng)絡(luò)安全(網(wǎng)絡(luò)安全(socket) 編程編程北京交通大學(xué)出版社北京交通大學(xué)出版社1.1.套接字套接字(socket)(socket)的引入的引入為了能夠方便的開發(fā)網(wǎng)絡(luò)應(yīng)用軟件,由美國伯克利大學(xué)在為了能夠方便的開發(fā)網(wǎng)絡(luò)應(yīng)用軟件,由美國伯克利大學(xué)在UnixUnix上推出了一種應(yīng)用程序訪問通信協(xié)議的操作系統(tǒng)調(diào)用上推出了一種應(yīng)用程序訪問通信協(xié)議的操作系統(tǒng)調(diào)用socket(socket(套接字套接字) )。socketsocket的出現(xiàn),使程序員可以很方便地訪問的出現(xiàn),使程序員可以很方便地訪問TCP/IPTCP/IP,從而開發(fā)各種網(wǎng)絡(luò)
2、應(yīng)用的程序。,從而開發(fā)各種網(wǎng)絡(luò)應(yīng)用的程序。隨著隨著UnixUnix的應(yīng)用推廣,套接字在編寫網(wǎng)絡(luò)軟件中得到了極大的應(yīng)用推廣,套接字在編寫網(wǎng)絡(luò)軟件中得到了極大的普及。后來,套接字又被引進(jìn)了的普及。后來,套接字又被引進(jìn)了WindowsWindows等操作系統(tǒng),成為開等操作系統(tǒng),成為開發(fā)網(wǎng)絡(luò)應(yīng)用程序的非常有效快捷的工具。發(fā)網(wǎng)絡(luò)應(yīng)用程序的非常有效快捷的工具。套接字存在于通信區(qū)域中。通信區(qū)域也叫地址族套接字存在于通信區(qū)域中。通信區(qū)域也叫地址族,它是一個,它是一個抽象的概念,抽象的概念,主要用于將通過套接字通信的進(jìn)程的共有特性綜合主要用于將通過套接字通信的進(jìn)程的共有特性綜合在一起。在一起。套接字通常只與同一
3、區(qū)域的套接字交換數(shù)據(jù)(也有可能套接字通常只與同一區(qū)域的套接字交換數(shù)據(jù)(也有可能跨區(qū)域通信,但這只在執(zhí)行了某種轉(zhuǎn)換進(jìn)程后才能實現(xiàn))??鐓^(qū)域通信,但這只在執(zhí)行了某種轉(zhuǎn)換進(jìn)程后才能實現(xiàn))。Windows SocketsWindows Sockets只支持一個通信區(qū)域:只支持一個通信區(qū)域:網(wǎng)際域網(wǎng)際域( ( AF_INETAF_INET) ),這個域被使用網(wǎng)際協(xié)議簇通信的,這個域被使用網(wǎng)際協(xié)議簇通信的進(jìn)程使用。進(jìn)程使用。北京交通大學(xué)出版社北京交通大學(xué)出版社2.2.網(wǎng)絡(luò)字節(jié)順序網(wǎng)絡(luò)字節(jié)順序不同的計算機(jī)存放多字節(jié)值的順序不同,有的機(jī)器在起始地不同的計算機(jī)存放多字節(jié)值的順序不同,有的機(jī)器在起始地址存放低位字
4、節(jié)址存放低位字節(jié)( (低位先存低位先存) ),有的機(jī)器在起始地址存放高位字節(jié),有的機(jī)器在起始地址存放高位字節(jié)( (高位先存高位先存) )?;诨贗ntelIntel的的CPUCPU,即我們常用的,即我們常用的PCPC機(jī)采用的是低位先存。為機(jī)采用的是低位先存。為保證數(shù)據(jù)的正確性,在網(wǎng)絡(luò)協(xié)議中需要指定網(wǎng)絡(luò)字節(jié)順序。保證數(shù)據(jù)的正確性,在網(wǎng)絡(luò)協(xié)議中需要指定網(wǎng)絡(luò)字節(jié)順序。TCP/IPTCP/IP協(xié)議使用協(xié)議使用1616位整數(shù)和位整數(shù)和3232位整數(shù)的高位先存格式位整數(shù)的高位先存格式。北京交通大學(xué)出版社北京交通大學(xué)出版社客戶機(jī)服務(wù)器模式客戶機(jī)服務(wù)器模式1)1)在在TCP/IPTCP/IP網(wǎng)絡(luò)應(yīng)用中,通信
5、的兩個進(jìn)程間相互作用的主要網(wǎng)絡(luò)應(yīng)用中,通信的兩個進(jìn)程間相互作用的主要模式是客戶機(jī)模式是客戶機(jī)/ /服務(wù)器模式服務(wù)器模式(client/server)(client/server),即客戶向服務(wù)器提,即客戶向服務(wù)器提出請求,服務(wù)器接收到請求后,提供相應(yīng)的服務(wù)。出請求,服務(wù)器接收到請求后,提供相應(yīng)的服務(wù)。2)2)客戶機(jī)客戶機(jī)/ /服務(wù)器模式的建立基于以下兩點(diǎn):首先,建立網(wǎng)服務(wù)器模式的建立基于以下兩點(diǎn):首先,建立網(wǎng)絡(luò)的起因是網(wǎng)絡(luò)中軟硬件資源、運(yùn)算能力和信息不均等,需要共絡(luò)的起因是網(wǎng)絡(luò)中軟硬件資源、運(yùn)算能力和信息不均等,需要共享,從而造就擁有眾多資源的主機(jī)提供服務(wù),資源較少的客戶請享,從而造就擁有眾多
6、資源的主機(jī)提供服務(wù),資源較少的客戶請求服務(wù)這一非對等作用。其次,網(wǎng)間進(jìn)程通信完全是異步的,相求服務(wù)這一非對等作用。其次,網(wǎng)間進(jìn)程通信完全是異步的,相互通信的進(jìn)程間既不存在父子關(guān)系,又不共享內(nèi)存緩沖區(qū),因此互通信的進(jìn)程間既不存在父子關(guān)系,又不共享內(nèi)存緩沖區(qū),因此需要一種機(jī)制為希望通信的進(jìn)程間建立聯(lián)系,為二者的數(shù)據(jù)交換需要一種機(jī)制為希望通信的進(jìn)程間建立聯(lián)系,為二者的數(shù)據(jù)交換提供同步,這就是基于客戶機(jī)提供同步,這就是基于客戶機(jī)/ /服務(wù)器模式的服務(wù)器模式的TCP/IPTCP/IP。北京交通大學(xué)出版社北京交通大學(xué)出版社客戶機(jī)服務(wù)器模式客戶機(jī)服務(wù)器模式客戶機(jī)客戶機(jī)/ /服務(wù)器模式在操作過程中采取的是主動
7、請求的方式。服務(wù)器模式在操作過程中采取的是主動請求的方式。 首先服務(wù)器方要先啟動首先服務(wù)器方要先啟動,并根據(jù)請求提供相應(yīng)的服務(wù):,并根據(jù)請求提供相應(yīng)的服務(wù):打開一個通信通道并告知本地主機(jī),它愿意在某一地址和端口上打開一個通信通道并告知本地主機(jī),它愿意在某一地址和端口上接收客戶請求。接收客戶請求。等待客戶請求到達(dá)該端口。等待客戶請求到達(dá)該端口。接收到重復(fù)服務(wù)請求,處理該請求并發(fā)送應(yīng)答信號。接收到并發(fā)接收到重復(fù)服務(wù)請求,處理該請求并發(fā)送應(yīng)答信號。接收到并發(fā)服務(wù)請求,要激活一個新的進(jìn)程服務(wù)請求,要激活一個新的進(jìn)程( (或線程或線程) )來處理這個客戶請求。來處理這個客戶請求。新進(jìn)程新進(jìn)程( (或線程
8、或線程) ) 處理此客戶請求,并不需要對其它請求作出應(yīng)處理此客戶請求,并不需要對其它請求作出應(yīng)答。服務(wù)完成后,關(guān)閉此新進(jìn)程與客戶的通信鏈路,并終止。答。服務(wù)完成后,關(guān)閉此新進(jìn)程與客戶的通信鏈路,并終止。返回第二步,等待另一客戶請求。返回第二步,等待另一客戶請求。關(guān)閉服務(wù)器。關(guān)閉服務(wù)器。 客戶方:客戶方:打開一個通信通道,并連接到服務(wù)器所在主機(jī)的特定端口。打開一個通信通道,并連接到服務(wù)器所在主機(jī)的特定端口。向服務(wù)器發(fā)服務(wù)請求報文,等待并接收應(yīng)答;繼續(xù)提出請求。向服務(wù)器發(fā)服務(wù)請求報文,等待并接收應(yīng)答;繼續(xù)提出請求。請求結(jié)束后關(guān)閉通信通道并終止。請求結(jié)束后關(guān)閉通信通道并終止。北京交通大學(xué)出版社北京交
9、通大學(xué)出版社Windows SocketsWindows Sockets的實現(xiàn)的實現(xiàn)Windows SocketsWindows Sockets是是Microsoft WindowsMicrosoft Windows的網(wǎng)絡(luò)程序設(shè)計接口,的網(wǎng)絡(luò)程序設(shè)計接口,它是從它是從Berkeley SocketsBerkeley Sockets擴(kuò)展而來的,以動態(tài)鏈接庫的形式提供擴(kuò)展而來的,以動態(tài)鏈接庫的形式提供給我們使用。給我們使用。Windows SocketsWindows Sockets在繼承了在繼承了Berkeley SocketsBerkeley Sockets主要主要特征的基礎(chǔ)上,又對它進(jìn)行了重
10、要擴(kuò)充。這些擴(kuò)充主要是提供了特征的基礎(chǔ)上,又對它進(jìn)行了重要擴(kuò)充。這些擴(kuò)充主要是提供了一些異步函數(shù),并增加了符合一些異步函數(shù),并增加了符合WindowsWindows消息驅(qū)動特性的網(wǎng)絡(luò)事件消息驅(qū)動特性的網(wǎng)絡(luò)事件異步選擇機(jī)制。異步選擇機(jī)制。Windows Sockets 1.1Windows Sockets 1.1和和Berkeley SocketsBerkeley Sockets都是基于都是基于TCP/IPTCP/IP協(xié)議的;協(xié)議的;Windows Sockets 2Windows Sockets 2從從Windows Sockets 1.1Windows Sockets 1.1發(fā)展而來,發(fā)展而
11、來,與協(xié)議無關(guān)并向下兼容,可以使用任何底層傳輸協(xié)議提供的通信與協(xié)議無關(guān)并向下兼容,可以使用任何底層傳輸協(xié)議提供的通信能力,來為上層應(yīng)用程序完成網(wǎng)絡(luò)數(shù)據(jù)通訊,而不關(guān)心底層網(wǎng)絡(luò)能力,來為上層應(yīng)用程序完成網(wǎng)絡(luò)數(shù)據(jù)通訊,而不關(guān)心底層網(wǎng)絡(luò)鏈路的通訊情況,真正實現(xiàn)了底層網(wǎng)絡(luò)通訊對應(yīng)用程序的透明。鏈路的通訊情況,真正實現(xiàn)了底層網(wǎng)絡(luò)通訊對應(yīng)用程序的透明。北京交通大學(xué)出版社北京交通大學(xué)出版社套接字的類型套接字的類型1)1)流式套接字流式套接字(SOCK_STREAMSOCK_STREAM)提供面向連接、可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)無差錯、無重復(fù)提供面向連接、可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)無差錯、無重復(fù)的發(fā)送,且按發(fā)送順序
12、接收。的發(fā)送,且按發(fā)送順序接收。2)2)數(shù)據(jù)報式套接字?jǐn)?shù)據(jù)報式套接字(SOCK_DGRAMSOCK_DGRAM)提供無連接服務(wù)。數(shù)據(jù)包以獨(dú)立包形式發(fā)送,不提供無錯保提供無連接服務(wù)。數(shù)據(jù)包以獨(dú)立包形式發(fā)送,不提供無錯保證,數(shù)據(jù)可能丟失或重復(fù),并且接收順序混亂。證,數(shù)據(jù)可能丟失或重復(fù),并且接收順序混亂。3)3)原始套接字原始套接字(SOCK_RAWSOCK_RAW)北京交通大學(xué)出版社北京交通大學(xué)出版社網(wǎng)絡(luò)安全編程基本函數(shù)網(wǎng)絡(luò)安全編程基本函數(shù)北京交通大學(xué)出版社北京交通大學(xué)出版社1 1、SOCKETSOCKET類型類型SOCKET是socket套接字類型,在WINSOCK2.H中有如下定義:typed
13、ef unsigned int u_int;typedef u_int SOCKET;可知套接字實際上就是一個無符號整型,它將被Socket環(huán)境管理和使用。套接字的使用流程:被創(chuàng)建、設(shè)置、用來發(fā)送和接收數(shù)據(jù),最后會被關(guān)閉。 北京交通大學(xué)出版社北京交通大學(xué)出版社2 WORD2 WORD類型、類型、MAKEWORDMAKEWORD、LOBYTELOBYTE和和HIBYTEHIBYTE宏宏WORDWORD類型是一個類型是一個1616位的無符號整型位的無符號整型,在,在WTYPES.HWTYPES.H中被定義為:中被定義為:typedef unsigned short typedef unsigned
14、 short WORDWORD; ;目的目的: :是提供兩個字節(jié)的存儲,在是提供兩個字節(jié)的存儲,在SocketSocket中這兩個字節(jié)可以表示主版本號和副中這兩個字節(jié)可以表示主版本號和副版本號。使用版本號。使用MAKEWORDMAKEWORD宏可以給一個宏可以給一個WORDWORD類型賦值。類型賦值。例如例如: :要表示主版本號要表示主版本號2 2,副版本號,副版本號0 0,可以使用以下代碼:,可以使用以下代碼:WORD wVersionRequested;WORD wVersionRequested;wVersionRequested = MAKEWORD( 2, 0 ); wVersion
15、Requested = MAKEWORD( 2, 0 ); 注意低位內(nèi)存存儲主版本號注意低位內(nèi)存存儲主版本號2 2,高位內(nèi)存存儲副版本號,高位內(nèi)存存儲副版本號0 0,其值為,其值為0 x00020 x0002。使用宏使用宏LOBYTELOBYTE可以讀取可以讀取WORDWORD的低位字節(jié),的低位字節(jié),HIBYTEHIBYTE可以讀取高位字節(jié)??梢宰x取高位字節(jié)。北京交通大學(xué)出版社北京交通大學(xué)出版社3 WSAStartup ()3 WSAStartup ()函數(shù)函數(shù)WSAStartupWSAStartup函數(shù)被用來函數(shù)被用來初始化初始化SocketSocket環(huán)境環(huán)境,它的定義如下:,它的定義如下
16、:int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);返回值返回值: :整型整型; ;若返回值為若返回值為0 0,則初始化成功,若不為,則初始化成功,若不為0 0則失敗。則失敗。調(diào)用方式調(diào)用方式: :PASCALPASCAL(即標(biāo)準(zhǔn)類型,(即標(biāo)準(zhǔn)類型,PASCALPASCAL等于等于_stdcall_stdcall)參數(shù)參數(shù): :第一個參數(shù)為第一個參數(shù)為WORDWORD
17、類型,指明了類型,指明了SocketSocket的版本號的版本號第二個參數(shù)為第二個參數(shù)為WSADATAWSADATA類型的指針。類型的指針。北京交通大學(xué)出版社北京交通大學(xué)出版社4 WSADATA4 WSADATA類型和類型和LPWSADATALPWSADATA類型類型WSADATAWSADATA類型是一個結(jié)構(gòu),描述了類型是一個結(jié)構(gòu),描述了SocketSocket庫的一些相關(guān)信息庫的一些相關(guān)信息,其結(jié)構(gòu)定,其結(jié)構(gòu)定義如下:義如下:typedef struct typedef struct WSADataWSAData WORD wVersion; WORD wVersion; WORD wHig
18、hVersion; WORD wHighVersion; char szDescriptionWSADESCRIPTION_LEN+1; char szDescriptionWSADESCRIPTION_LEN+1; char szSystemStatusWSASYS_STATUS_LEN+1; char szSystemStatusWSASYS_STATUS_LEN+1; unsigned short iMaxSockets; unsigned short iMaxSockets; unsigned short iMaxUdpDg; unsigned short iMaxUdpDg; cha
19、r FAR char FAR * * lpVendorInfo; lpVendorInfo; WSADATAWSADATA; ;typedef WSADATA FAR typedef WSADATA FAR * *LPWSADATALPWSADATA; ;wVersion:wVersion:存儲了存儲了SocketSocket的版本類型。的版本類型。LPWSADATA:LPWSADATA:是是WSADATAWSADATA的指針類型。的指針類型。它們不用程序員手動填寫,而是通過它們不用程序員手動填寫,而是通過SocketSocket的初始化函數(shù)的初始化函數(shù)WSAStartupWSAStartup
20、讀讀取出來。取出來。北京交通大學(xué)出版社北京交通大學(xué)出版社5 socket ()5 socket ()函數(shù)函數(shù)socketsocket的創(chuàng)建函數(shù),其定義為:的創(chuàng)建函數(shù),其定義為:SOCKET PASCAL FAR socket (int af, int type, int protocol);SOCKET PASCAL FAR socket (int af, int type, int protocol);int af:int af:代表網(wǎng)絡(luò)地址族,目前只有一種取值是有效的,即代表網(wǎng)絡(luò)地址族,目前只有一種取值是有效的,即AF_INETAF_INET,代表代表internetinternet地址族
21、;地址族;int type:int type:代表網(wǎng)絡(luò)協(xié)議類型,代表網(wǎng)絡(luò)協(xié)議類型,SOCK_DGRAMSOCK_DGRAM代表代表UDPUDP協(xié)議,協(xié)議,SOCK_STREAMSOCK_STREAM代表代表TCPTCP協(xié)議;協(xié)議;int protocol:int protocol:指定網(wǎng)絡(luò)地址族的特殊協(xié)議,目前無用,賦值指定網(wǎng)絡(luò)地址族的特殊協(xié)議,目前無用,賦值0 0即可。即可。創(chuàng)建成功則返回值為創(chuàng)建成功則返回值為SOCKETSOCKET,若返回,若返回INVALID_SOCKETINVALID_SOCKET則失敗。則失敗。北京交通大學(xué)出版社北京交通大學(xué)出版社6 bind () ()函數(shù)函數(shù)in
22、t bind( SOCKET int bind( SOCKET s s, const struct sockaddr FAR , const struct sockaddr FAR * *namename, int , int namelen namelen ););參數(shù):參數(shù):s s:指定要綁定的套接字指定要綁定的套接字 const struct sockaddr FAR const struct sockaddr FAR * *namename:了該套接字的本地地址信息,是指向了該套接字的本地地址信息,是指向sockaddrsockaddr結(jié)構(gòu)的指針變結(jié)構(gòu)的指針變量,由于該地址結(jié)構(gòu)是為所有
23、的地址家族準(zhǔn)備的,這個結(jié)構(gòu)可能量,由于該地址結(jié)構(gòu)是為所有的地址家族準(zhǔn)備的,這個結(jié)構(gòu)可能(通常會)隨所使用的網(wǎng)絡(luò)協(xié)議不同而不同(通常會)隨所使用的網(wǎng)絡(luò)協(xié)議不同而不同Namelen:Namelen:指定該地址結(jié)構(gòu)的長度。指定該地址結(jié)構(gòu)的長度。北京交通大學(xué)出版社北京交通大學(xué)出版社6 bind () ()函數(shù)函數(shù)int bind( SOCKET int bind( SOCKET s s, const struct , const struct sockaddrsockaddr FAR FAR * *namename, int , int namelen namelen ););sockaddrsock
24、addr結(jié)構(gòu)定義如下:結(jié)構(gòu)定義如下: struct sockaddr struct sockaddr u_short sa_family; u_short sa_family; char sa_data14; char sa_data14; ; ; sa_family:sa_family:指定該地址家族,在這里必須設(shè)為指定該地址家族,在這里必須設(shè)為AF_INETAF_INET。sa_data:sa_data:僅僅是表示要求一塊內(nèi)存分配區(qū),起到占位的作用,該區(qū)域僅僅是表示要求一塊內(nèi)存分配區(qū),起到占位的作用,該區(qū)域中指定與協(xié)議相關(guān)的具體地址信息。由于實際要求的只是內(nèi)存區(qū),中指定與協(xié)議相關(guān)的具體地址
25、信息。由于實際要求的只是內(nèi)存區(qū),所以對于不同的協(xié)議家族,用不同的結(jié)構(gòu)來替換所以對于不同的協(xié)議家族,用不同的結(jié)構(gòu)來替換sockaddrsockaddr。除了。除了sa_familysa_family外,外,sockaddrsockaddr是按網(wǎng)絡(luò)字節(jié)順序表示的。在是按網(wǎng)絡(luò)字節(jié)順序表示的。在TCP/IPTCP/IP中,中,我們可以用我們可以用sockaddr_insockaddr_in結(jié)構(gòu)替換結(jié)構(gòu)替換sockaddrsockaddr,以方便我們填寫地,以方便我們填寫地址信息。址信息。 北京交通大學(xué)出版社北京交通大學(xué)出版社續(xù):sockaddr_in的定義如下:的定義如下: struct sockad
26、dr_in short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero8; ; 其中,其中,sin_family表示地址族,對于表示地址族,對于IP地址,地址,sin_family成員將一直是成員將一直是AF_INET。成員成員sin_port指定的是將要分配給套接字的端口。成員指定的是將要分配給套接字的端口。成員sin_addr給出的是套接字的主機(jī)給出的是套接字的主機(jī)IP地址。而成員地址。而成員sin_zero只是一個填充數(shù),以使只是一個填充數(shù),以使sockaddr_in結(jié)構(gòu)和結(jié)構(gòu)和soc
27、kaddr結(jié)構(gòu)的長結(jié)構(gòu)的長度一樣。如果這個函數(shù)調(diào)用成功,它將返回度一樣。如果這個函數(shù)調(diào)用成功,它將返回0。如果調(diào)用失敗,這個函數(shù)就會返回一。如果調(diào)用失敗,這個函數(shù)就會返回一個個SOCKET_ERROR,錯誤信息可以通過,錯誤信息可以通過WSAGetLastError函數(shù)返回。函數(shù)返回。 將將IP地址指定為地址指定為INADDR_ANY,允許套接字向任何分配給本地機(jī)器的,允許套接字向任何分配給本地機(jī)器的IP地址發(fā)送地址發(fā)送或接收數(shù)據(jù)。多數(shù)情況下,每個機(jī)器只有一個或接收數(shù)據(jù)。多數(shù)情況下,每個機(jī)器只有一個IP地址,但有的機(jī)器可能會有多個網(wǎng)卡,地址,但有的機(jī)器可能會有多個網(wǎng)卡,每個網(wǎng)卡都可以有自己的每
28、個網(wǎng)卡都可以有自己的IP地址,用地址,用INADDR_ANY可以簡化應(yīng)用程序的編寫。將地可以簡化應(yīng)用程序的編寫。將地址指定為址指定為INADDR_ANY,允許一個獨(dú)立應(yīng)用接受發(fā)自多個接口的回應(yīng)。如果我們只,允許一個獨(dú)立應(yīng)用接受發(fā)自多個接口的回應(yīng)。如果我們只想讓套接字使用多個想讓套接字使用多個IP中的一個地址,就必須指定實際地址,要做到這一點(diǎn),可以用中的一個地址,就必須指定實際地址,要做到這一點(diǎn),可以用inet_addr()函數(shù),這個函數(shù)需要一個字符串作為其參數(shù),該字符串指定了以點(diǎn)分十進(jìn)函數(shù),這個函數(shù)需要一個字符串作為其參數(shù),該字符串指定了以點(diǎn)分十進(jìn)制格式表示的制格式表示的IP地址地址(如如19
29、2.168.0.16)。而且。而且inet_addr()函數(shù)會返回一個適合分配給函數(shù)會返回一個適合分配給S_addr的的u_long類型的數(shù)值。類型的數(shù)值。inet_ntoa()函數(shù)會完成相反的轉(zhuǎn)換,它接受一個函數(shù)會完成相反的轉(zhuǎn)換,它接受一個in_addr結(jié)構(gòu)體類型的參數(shù)并返回一個以點(diǎn)分十進(jìn)制格式表示的結(jié)構(gòu)體類型的參數(shù)并返回一個以點(diǎn)分十進(jìn)制格式表示的IP地址字符串。地址字符串。北京交通大學(xué)出版社北京交通大學(xué)出版社7 setsockopt ()7 setsockopt ()函數(shù)函數(shù)這個函數(shù)用來這個函數(shù)用來設(shè)置設(shè)置SocketSocket的屬性的屬性,若不能正確設(shè)置,若不能正確設(shè)置socketso
30、cket屬性,則數(shù)據(jù)屬性,則數(shù)據(jù)的發(fā)送和接收會失敗。定義如下:的發(fā)送和接收會失敗。定義如下:int PASCAL FAR setsockopt (SOCKET s, int level, int optname,int PASCAL FAR setsockopt (SOCKET s, int level, int optname, const char FAR const char FAR * * optval, int optlen); optval, int optlen);返回值返回值: :intint類型,類型,0 0代表成功,代表成功,SOCKET_ERRORSOCKET_ERROR
31、代表有錯誤發(fā)生代表有錯誤發(fā)生。SOCKET sSOCKET s:代表要設(shè)置的套接字;代表要設(shè)置的套接字;int levelint level:代表要設(shè)置的屬性所處的層次,層次包含以下取值:代表要設(shè)置的屬性所處的層次,層次包含以下取值:SOL_SOCKETSOL_SOCKET代表套代表套接字層次;接字層次;IPPROTO_TCPIPPROTO_TCP代表代表TCPTCP協(xié)議層次,協(xié)議層次,IPPROTO_IPIPPROTO_IP代表代表IPIP協(xié)議層次(后協(xié)議層次(后面兩個我都沒有用過);面兩個我都沒有用過);int optnameint optname:代表設(shè)置參數(shù)的名稱,代表設(shè)置參數(shù)的名稱,
32、SO_BROADCASTSO_BROADCAST代表允許發(fā)送廣播數(shù)據(jù)的屬性,其代表允許發(fā)送廣播數(shù)據(jù)的屬性,其它屬性可參考它屬性可參考MSDNMSDN;const char FAR const char FAR * * optval optval:代表指向存儲參數(shù)數(shù)值的指針,注意這里可能要使用代表指向存儲參數(shù)數(shù)值的指針,注意這里可能要使用reinterpret_castreinterpret_cast類型轉(zhuǎn)換;類型轉(zhuǎn)換;int optlenint optlen:代表存儲參數(shù)數(shù)值變量的長度。代表存儲參數(shù)數(shù)值變量的長度。北京交通大學(xué)出版社北京交通大學(xué)出版社8 8 sockaddr_insockadd
33、r_in、in_addrin_addr類型,類型,inet_addrinet_addr、inet_ntoainet_ntoa函數(shù)函數(shù)sockaddr_insockaddr_in定義了定義了socketsocket發(fā)送和接收數(shù)據(jù)包的地址發(fā)送和接收數(shù)據(jù)包的地址,定義如下:,定義如下:struct struct sockaddr_in sockaddr_in short sin_family; short sin_family; u_short sin_port; u_short sin_port; struct in_addrstruct in_addr sin_addrsin_addr; ; c
34、har sin_zero8; char sin_zero8;其中其中in_addrin_addr的定義如下:的定義如下:struct struct in_addrin_addr union struct u_char s_b1,s_b2,s_b3,s_b4; union struct u_char s_b1,s_b2,s_b3,s_b4; S_un_b;S_un_b; struct u_short s_w1,s_w2; S_un_w; struct u_short s_w1,s_w2; S_un_w; u_long u_long S_addrS_addr; ; S_unS_un; ;北京交通大
35、學(xué)出版社北京交通大學(xué)出版社struct in_addr union struct u_char s_b1,s_b2,s_b3,s_b4;S_un_b; struct u_short s_w1,s_w2; S_un_w; u_long S_addr; S_un;首先闡述首先闡述in_addrin_addr的含義,很顯然它是一個存儲的含義,很顯然它是一個存儲ipip地址的聯(lián)地址的聯(lián)合體,有三種表達(dá)方式:合體,有三種表達(dá)方式:第一種:用四個字節(jié)來表示第一種:用四個字節(jié)來表示IPIP地址的四個數(shù)字;地址的四個數(shù)字;第二種:用兩個雙字節(jié)來表示第二種:用兩個雙字節(jié)來表示IPIP地址;地址;第三種:用一個長
36、整型來表示第三種:用一個長整型來表示IPIP地址。地址。給給in_addrin_addr賦值的一種最簡單方法是使用賦值的一種最簡單方法是使用inet_addrinet_addr函數(shù),它函數(shù),它可以可以把一個代表把一個代表IPIP地址的字符串賦值轉(zhuǎn)換為地址的字符串賦值轉(zhuǎn)換為in_addrin_addr類型類型,如,如addrto.sin_addr.s_addr=inet_addr(192.168.0.2);addrto.sin_addr.s_addr=inet_addr(192.168.0.2);其反函數(shù)是其反函數(shù)是inet_inet_n ntotoa()a():network to ascii
37、 將網(wǎng)絡(luò)地址轉(zhuǎn)換成將網(wǎng)絡(luò)地址轉(zhuǎn)換成“.”.”點(diǎn)隔的字符串格式,即把一個點(diǎn)隔的字符串格式,即把一個in_addrin_addr類型轉(zhuǎn)換為一個字符串。類型轉(zhuǎn)換為一個字符串。北京交通大學(xué)出版社北京交通大學(xué)出版社struct sockaddr_in short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero8;sockaddr_insockaddr_in的含義比的含義比in_addrin_addr的含義要廣泛,其各個字段的含義和取值如下:的含義要廣泛,其各個字段的含義和取值如下:short sin_familys
38、hort sin_family:代表網(wǎng)絡(luò)地址族,如前所述,只能取值代表網(wǎng)絡(luò)地址族,如前所述,只能取值A(chǔ)F_INETAF_INET;u_short sin_portu_short sin_port:代表代表IPIP地址端口,由程序員指定;地址端口,由程序員指定;struct in_addr sin_addrstruct in_addr sin_addr:代表代表IPIP地址;地址;char sin_zero8char sin_zero8:是為了保證是為了保證sockaddr_insockaddr_in與與SOCKADDRSOCKADDR類型的長度相等而填充進(jìn)來的字段。類型的長度相等而填充進(jìn)來的字
39、段。北京交通大學(xué)出版社北京交通大學(xué)出版社程序示例:程序示例:以下代表指明了廣播地址,端口號為以下代表指明了廣播地址,端口號為78617861的一個地址:的一個地址: sockaddr_in addrto; sockaddr_in addrto; /發(fā)往的地址發(fā)往的地址 memset(&addrto,0,sizeof(addrto);memset(&addrto,0,sizeof(addrto); addrto. addrto.sin_familysin_family = AF_INET; = AF_INET; /地址類型為地址類型為internetworkinternetwor
40、k addrto. addrto.sin_addr.s_addrsin_addr.s_addr = INADDR_BROADCAST; = INADDR_BROADCAST; /設(shè)置設(shè)置ipip為廣播地址為廣播地址 addrto.addrto.sin_port sin_port = htons(7861); = htons(7861); /端口號為端口號為78617861北京交通大學(xué)出版社北京交通大學(xué)出版社9 sockaddr ()9 sockaddr ()類型類型sockaddrsockaddr類型是用來表示類型是用來表示SocketSocket地址的類型,同上面的地址的類型,同上面的soc
41、kaddr_insockaddr_in類類型相比,型相比,sockaddrsockaddr的適用范圍更廣,因為的適用范圍更廣,因為sockaddr_insockaddr_in只適用于只適用于TCP/IPTCP/IP地址。地址。SockaddrSockaddr的定義如下:的定義如下:struct sockaddr struct sockaddr u_short sa_family;u_short sa_family; char sa_data14;char sa_data14; ; 可知可知sockaddrsockaddr有有1616個字節(jié),而個字節(jié),而sockaddr_insockaddr_i
42、n也有也有1616個字節(jié),所以個字節(jié),所以sockaddr_insockaddr_in是可以強(qiáng)制類型轉(zhuǎn)換為是可以強(qiáng)制類型轉(zhuǎn)換為sockaddrsockaddr的。事實上也往往使用這種方法。的。事實上也往往使用這種方法。北京交通大學(xué)出版社北京交通大學(xué)出版社10 Sleep ()10 Sleep ()函數(shù)函數(shù)線程掛起函數(shù),表示線程掛起一段時間。線程掛起函數(shù),表示線程掛起一段時間。Sleep(1000)Sleep(1000)表示表示掛起一秒。定義于掛起一秒。定義于WINBASE.HWINBASE.H頭文件中。頭文件中。WINBASE.HWINBASE.H又被包含于又被包含于WINDOWS.HWIND
43、OWS.H中,然后中,然后WINDOWS.HWINDOWS.H被被WINSOCK2.HWINSOCK2.H包含。包含。所以使用所以使用SleepSleep函數(shù)不需要包含其它頭文件。函數(shù)不需要包含其它頭文件。北京交通大學(xué)出版社北京交通大學(xué)出版社11 sendto()11 sendto()函數(shù)函數(shù)在在SocketSocket中有兩套發(fā)送和接收函數(shù),一是中有兩套發(fā)送和接收函數(shù),一是sendtosendto和和recvfromrecvfrom;二是;二是sendsend和和recvrecv。前一套在函數(shù)參數(shù)中要指明地址;而后一套需要先。前一套在函數(shù)參數(shù)中要指明地址;而后一套需要先將套接字和一個地址綁定
44、,然后直接發(fā)送和接收,不需綁定地址。將套接字和一個地址綁定,然后直接發(fā)送和接收,不需綁定地址。sendtosendto的定義如下:的定義如下:int PASCAL FAR sendto (SOCKET s, const char FAR int PASCAL FAR sendto (SOCKET s, const char FAR * * buf, int buf, int len, int flags, const struct sockaddr FAR len, int flags, const struct sockaddr FAR * *to, int to, int tolen);t
45、olen);第一個參數(shù)就是套接字;第一個參數(shù)就是套接字;第二個參數(shù)是要傳送的數(shù)據(jù)指針;第二個參數(shù)是要傳送的數(shù)據(jù)指針;第三個參數(shù)是要傳送的數(shù)據(jù)長度(字節(jié)數(shù));第三個參數(shù)是要傳送的數(shù)據(jù)長度(字節(jié)數(shù));第四個參數(shù)是傳送方式的標(biāo)識,如果不需要特殊要求則可以設(shè)置為第四個參數(shù)是傳送方式的標(biāo)識,如果不需要特殊要求則可以設(shè)置為0 0,其它值請參考,其它值請參考MSDNMSDN;第五個參數(shù)是目標(biāo)地址,注意這里使用的是第五個參數(shù)是目標(biāo)地址,注意這里使用的是sockaddrsockaddr的指針;的指針;第六個參數(shù)是地址的長度;第六個參數(shù)是地址的長度;返回值為整型,如果成功,則返回發(fā)送的字節(jié)數(shù),失敗則返回返回值為整
46、型,如果成功,則返回發(fā)送的字節(jié)數(shù),失敗則返回SOCKET_ERRORSOCKET_ERROR。北京交通大學(xué)出版社北京交通大學(xué)出版社12 WSAGetLastError()12 WSAGetLastError()函數(shù)函數(shù)該函數(shù)用來在該函數(shù)用來在SocketSocket相關(guān)相關(guān)APIAPI失敗后讀取錯誤碼,根據(jù)這些失敗后讀取錯誤碼,根據(jù)這些錯誤碼可以對照查出錯誤原因。錯誤碼可以對照查出錯誤原因。13 closesocket()13 closesocket()函數(shù)函數(shù)關(guān)閉套接字,其參數(shù)為關(guān)閉套接字,其參數(shù)為SOCKETSOCKET類型。成功返回類型。成功返回0 0,失敗返回,失敗返回SOCKET_E
47、RRORSOCKET_ERROR。 北京交通大學(xué)出版社北京交通大學(xué)出版社14 WSACleanup ()14 WSACleanup ()函數(shù)函數(shù)卸載卸載SocketSocket庫,釋放系統(tǒng)資源。庫,釋放系統(tǒng)資源。返回值為返回值為0 0表示成功,表示成功,SOCKET_ERRORSOCKET_ERROR表示失敗。表示失敗。北京交通大學(xué)出版社北京交通大學(xué)出版社下面是一個用下面是一個用UDPUDP發(fā)送廣播報文的程序示例發(fā)送廣播報文的程序示例:#include #include void main() SOCKET sock; /socket套接字套接字 char szMsg = this is a
48、UDP test package;/被發(fā)送的字段被發(fā)送的字段 /1./1.啟動啟動SOCKETSOCKET庫,版本為庫,版本為2.02.0 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 0 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( 0 != err ) /檢查檢查Socket初始化是否成功初始化是否成功 coutSocket2.0初始化失敗,初始化失敗,Exit!; return; /檢查檢查So
49、cket庫的版本是否為庫的版本是否為2.0 if (LOBYTE( wsaData.wVersion ) != 2 | HIBYTE( wsaData.wVersion ) != 0 ) WSACleanup( ); return; 北京交通大學(xué)出版社北京交通大學(xué)出版社/2./2.創(chuàng)建創(chuàng)建socketsocket, sock = socket(sock = socket( AF_INET, /internetwork: UDP, TCP, etc AF_INET, /internetwork: UDP, TCP, etc SOCK_DGRAM, /SOCK_DGRAM SOCK_DGRAM,
50、/SOCK_DGRAM說明是說明是UDPUDP類型類型 0 /protocol0 /protocol ); ); if (INVALID_SOCKET = sock ) if (INVALID_SOCKET = sock ) coutSocket coutSocket 創(chuàng)建失敗,創(chuàng)建失敗,Exit!;Exit!; return; return; /3. /3.設(shè)置該套接字為廣播類型,設(shè)置該套接字為廣播類型, bool opt = true;bool opt = true; setsockopt(sock, SOL_SOCKET, SO_BROADCAST, reinterpret_castch
51、ar FAR setsockopt(sock, SOL_SOCKET, SO_BROADCAST, reinterpret_cast(&opt), sizeof(opt);(&opt), sizeof(opt); /4. /4.設(shè)置發(fā)往的地址設(shè)置發(fā)往的地址 sockaddr_in addrto; /sockaddr_in addrto; /發(fā)往的地址發(fā)往的地址 memset(&addrto,0,sizeof(addrto);memset(&addrto,0,sizeof(addrto); addrto.sin_family = AF_INET; / addrto
52、.sin_family = AF_INET; /地址類型為地址類型為internetworkinternetwork addrto.sin_addr.s_addr = INADDR_BROADCAST; / addrto.sin_addr.s_addr = INADDR_BROADCAST; /設(shè)置設(shè)置ipip為廣播地址為廣播地址 addrto.sin_port = htons(7861); /addrto.sin_port = htons(7861); /端口號為端口號為78617861 int nlen=sizeof(addrto); int nlen=sizeof(addrto); un
53、signed int uIndex = 1; unsigned int uIndex = 1; 北京交通大學(xué)出版社北京交通大學(xué)出版社while(true)while(true) Sleep(1000); / Sleep(1000); /程序休眠一秒程序休眠一秒 /向廣播地址發(fā)送消息向廣播地址發(fā)送消息 if( sendto(sock, szMsg, strlen(szMsg), 0, if( sendto(sock, szMsg, strlen(szMsg), 0, (sockaddr(sockaddr* *)&addrto,nlen)&addrto,nlen) = SOCKET
54、_ERROR ) = SOCKET_ERROR ) coutWSAGetLastError()endl; coutWSAGetLastError()endl; else else coutuIndex+:an UDP package is sended.endl; coutuIndex+:an UDP package is sended.-設(shè)置設(shè)置-鏈接鏈接-對象對象/ /庫模塊庫模塊 3 3WINSOCK.DLLWINSOCK.DLL: : WINSOCKWINSOCK的動態(tài)連接庫,位于的動態(tài)連接庫,位于WINDOWSWINDOWS的安裝目錄下。的安裝目錄下。北京交通大學(xué)出版社北京交通大學(xué)出
55、版社服務(wù)器端操作服務(wù)器端操作 socketsocket(套接字)(套接字)1)1)在初始化階段調(diào)用在初始化階段調(diào)用WSAStartup()WSAStartup() 此函數(shù)在應(yīng)用程序中初始化此函數(shù)在應(yīng)用程序中初始化Windows Sockets DLL Windows Sockets DLL ,只有此函數(shù)調(diào)用成功后,應(yīng)用程序才可以再調(diào)用其他只有此函數(shù)調(diào)用成功后,應(yīng)用程序才可以再調(diào)用其他Windows Sockets DLLWindows Sockets DLL中的中的APIAPI函數(shù)。函數(shù)。在程式中調(diào)用該函數(shù)的形式如下:在程式中調(diào)用該函數(shù)的形式如下: int int WSAStartupWSAS
56、tartup(WORD wVersionRequested,LPWSADATA lpWSAData);(WORD wVersionRequested,LPWSADATA lpWSAData);北京交通大學(xué)出版社北京交通大學(xué)出版社int int WSAStartupWSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);(WORD wVersionRequested,LPWSADATA lpWSAData);wVersionRequestedwVersionRequested:用于指定準(zhǔn)備加載的用于指定準(zhǔn)備加載的WinsockWinsock庫
57、的版本。庫的版本。高位字節(jié)指定所需要的高位字節(jié)指定所需要的WinsockWinsock庫的副版本,而低庫的副版本,而低位字節(jié)則是主版本。位字節(jié)則是主版本。可用可用MAKEWORD(x,y)(MAKEWORD(x,y)(其中,其中,x x是高位字節(jié)是高位字節(jié),y y是低位是低位字節(jié)字節(jié)) )方便地獲得方便地獲得wVersionRequestedwVersionRequested的正確值。的正確值。 lpWSADatalpWSAData:是指向是指向WSADATAWSADATA結(jié)構(gòu)的指針,用來存儲系統(tǒng)傳回的結(jié)構(gòu)的指針,用來存儲系統(tǒng)傳回的關(guān)于加載的庫版本的資料,是一個結(jié)構(gòu)體。關(guān)于加載的庫版本的資料,
58、是一個結(jié)構(gòu)體。北京交通大學(xué)出版社北京交通大學(xué)出版社2)2)建立建立SocketSocket 初始化初始化WinSockWinSock的動態(tài)連接庫后,需要在服務(wù)器端建立一個監(jiān)的動態(tài)連接庫后,需要在服務(wù)器端建立一個監(jiān)聽的聽的SocketSocket,為此可以調(diào)用,為此可以調(diào)用Socket()Socket()函數(shù)用來建立這個監(jiān)聽的函數(shù)用來建立這個監(jiān)聽的SocketSocket,并定義此,并定義此SocketSocket所使用的通信協(xié)議。所使用的通信協(xié)議。定義方式:定義方式:SOCKETSOCKET PASCAL FAR PASCAL FAR socketsocket(int af, int type
59、, int protocol)(int af, int type, int protocol)參數(shù)參數(shù): : afaf: :address familyaddress family,目前只提供,目前只提供AF_INET(PAF_INET(PF_INET)F_INET); typetype:SocketSocket的類型的類型( (SOCK_STREAMSOCK_STREAM( (流格式流格式) )、SOCK_DGRAMSOCK_DGRAM( (數(shù)據(jù)報數(shù)據(jù)報格式格式); protocolprotocol:特殊的通訊協(xié)定特殊的通訊協(xié)定( (不指定則不指定則設(shè)為設(shè)為0 0) );此函數(shù)調(diào)用此函數(shù)調(diào)用
60、成功返回成功返回SocketSocket對象對象,失敗失敗則則返回返回INVALID_SOCKETINVALID_SOCKET( (調(diào)用調(diào)用WSAGetLastError()WSAGetLastError()可得知原因,所有可得知原因,所有WinSocket WinSocket 的函數(shù)都可以使用這個函數(shù)來獲取失敗的原因的函數(shù)都可以使用這個函數(shù)來獲取失敗的原因) )。北京交通大學(xué)出版社北京交通大學(xué)出版社3)3)綁定端口綁定端口為監(jiān)聽的為監(jiān)聽的SocketSocket指定一個地址及端口(指定一個地址及端口(PortPort),這樣客戶端),這樣客戶端才知道待會要連接哪一個地址的哪個端口,為此需調(diào)用才知道待會要連接哪一個地址的哪個端口,為此需調(diào)用bind()bin
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公安三基考試試題及答案
- 張夏公務(wù)員面試題及答案
- 吉林市英語六級試卷及答案
- 2025年區(qū)域經(jīng)濟(jì)學(xué)期末考試試卷及答案
- 2025年投資理財師資格考試試卷及答案
- 2025年教育技術(shù)與課程開發(fā)考試試卷及答案
- 2025年公司治理與風(fēng)險管理試題及答案分享
- 2025年中小學(xué)數(shù)學(xué)教育教學(xué)改革考試試卷及答案
- 2025年土木工程結(jié)構(gòu)設(shè)計考試試題及答案
- 2025年大學(xué)生心理健康教育測評試卷及答案
- 2025年入團(tuán)考試一覽無遺試題及答案
- 鐵路段擴(kuò)能改造站房及生產(chǎn)生活房屋工程方案投標(biāo)文件(技術(shù)方案)
- 2025四年級美術(shù)國測知識競賽題庫(104題附答案)
- 2025年《養(yǎng)老護(hù)理員》考試模擬練習(xí)題及答案
- 公司檔案及文件管理制度
- 2025年四川筠連縣國有資本投資運(yùn)營有限公司招聘筆試參考題庫含答案解析
- 2024年貴州遵義公開招聘社區(qū)工作者考試試題答案解析
- 14.第十四周 繃緊“防震弦”奏響“安全曲”
- 2025年湘教版初中地理七年級下冊重點(diǎn)知識點(diǎn)梳理與歸納
- 基底節(jié)腦出血護(hù)理查房
- 滾筒式柑橘分選機(jī)的設(shè)計
評論
0/150
提交評論