版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、2021/3/91套接字編程2021/3/92Socket簡介簡介 80年代初,人們在UNIX操作系統(tǒng)下實(shí)現(xiàn)TCP/IP協(xié)議。 研究人員為TCP/IP網(wǎng)絡(luò)通信開發(fā)了一個(gè)API(應(yīng)用程序接口)。 這個(gè)API稱為Socket接口(套接字)。 SOCKET接口是TCP/IP網(wǎng)絡(luò)最為通用的API,也是在INTERNET上進(jìn)行應(yīng)用開發(fā)最為通用的API。2021/3/93Socket簡介簡介 90年代初,Microsoft聯(lián)合了其他幾家公司共同制定了一套WINDOWS下的網(wǎng)絡(luò)編程接口,即WindowsSockets規(guī)范。 增加了一些異步函數(shù),并增加了符合Windows消息驅(qū)動(dòng)特性的網(wǎng)絡(luò)事件異步選擇機(jī)制。
2、WINDOWSSOCKETS規(guī)范是一套開放的、支持多種協(xié)議的Windows下的網(wǎng)絡(luò)編程接口。 從1991年的1.0版到1995年的2.0.8版,經(jīng)過不斷完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成為Windows網(wǎng)絡(luò)編程的事實(shí)上的標(biāo)準(zhǔn)。 在實(shí)際應(yīng)用中的WINDOWSSOKCETS規(guī)范主要有1.1版和2.0版。 兩者的最重要區(qū)別是1.1版只支持TCP/IP協(xié)議,而2.0版可以支持多協(xié)議。 2.0版有良好的向后兼容性,任何使用1.1版的源代碼,二進(jìn)制文件,應(yīng)用程序都可以不加修改地在2.0規(guī)范下使用。2021/3/94Socket簡介
3、簡介 SOCKET實(shí)際在計(jì)算機(jī)中提供了一個(gè)通信端口,可以通過這個(gè)端口與任何一個(gè)具有SOCKET接口的計(jì)算機(jī)通信。 應(yīng)用程序在網(wǎng)絡(luò)上傳輸,接收的信息都通過這個(gè)SOCKET接口來實(shí)現(xiàn)。 在應(yīng)用開發(fā)中就像使用文件句柄一樣,可以對SOCKET句柄進(jìn)行讀,寫操作。2021/3/95Socket的機(jī)制是什么的機(jī)制是什么 簡單的把Socket理解為一個(gè)可以連通網(wǎng)絡(luò)上不同計(jì)算機(jī)程序之間的管道,把一堆數(shù)據(jù)從管道的A端扔進(jìn)去,則會(huì)從管道的B端(也許同時(shí)還可以從C、D、E、F端冒出來)。 管道的端口由兩個(gè)因素來唯一確認(rèn),即機(jī)器的IP地址和程序所使用的端口號(hào)。 端口號(hào)就是程序員指定的一個(gè)數(shù)字,如:http的80端口和
4、ftp的21端口。 建議大家自己寫程序不要使用太小的端口號(hào),它們一般被系統(tǒng)占用了,也不要使用一些著名的端口,一般來說使用10005000之內(nèi)的端口比較好。2021/3/96Socket的機(jī)制是什么的機(jī)制是什么 Socket可以支持?jǐn)?shù)據(jù)的發(fā)送和接收 它定義一種稱為套接字的變量,發(fā)送數(shù)據(jù)時(shí)首先創(chuàng)建套接字,然后使用該套接字的sendto等方法對準(zhǔn)某個(gè)IP/端口進(jìn)行數(shù)據(jù)發(fā)送 接收端也首先創(chuàng)建套接字,然后將該套接字綁定到一個(gè)IP/端口上,所有發(fā)向此端口的數(shù)據(jù)會(huì)被該套接字的recv等函數(shù)讀出。如同讀出文件中的數(shù)據(jù)一樣。2021/3/97所需的頭文件、庫文件和所需的頭文件、庫文件和DLL 最廣泛的Windo
5、wsSocket2.0版本,所需的一些文件如下(以安裝了VC6為例說明其物理位置): (1)頭文件winsock2.h,通常處于C:“ProgramFiles”MicrosoftVisualStudio“VC98”INCLUDE;查看該頭文件可知其中又包含了windows.h和pshpack4.h頭文件,因此在windows中的一些常用API都可以使用 (2)庫文件Ws2_32.lib,通常處于C:ProgramFilesMicrosoftVisualStudioVC98Lib; (3)DLL文件Ws2_32.dll,通常處于C:WINDOWSsystem32。2021/3/98編寫編寫Soc
6、ket程序需要的編程基礎(chǔ)程序需要的編程基礎(chǔ) (1)C+語法; (2)一點(diǎn)windowsSDK的基礎(chǔ),了解一些SDK的數(shù)據(jù)類型與API的調(diào)用方式; (3)一點(diǎn)編譯、鏈接和執(zhí)行的技術(shù)。2021/3/99UDP 所謂UDP,就是發(fā)送出去就不管的一種網(wǎng)絡(luò)協(xié)議。 UDP編程的發(fā)送端只管發(fā)送就可以了,不用檢查網(wǎng)絡(luò)連接狀態(tài)。 下面用例1來說明怎樣編寫UDP,并會(huì)詳細(xì)解釋每個(gè)API和數(shù)據(jù)類型。2021/3/910SOCKET類型類型 SOCKET是socket套接字類型,在WINSOCK2.H中有如下定義: typedefunsignedintu_int; typedefu_intSOCKET; 可知套接字實(shí)
7、際上就是一個(gè)無符號(hào)整型,它將被Socket環(huán)境管理和使用。 套接字將被創(chuàng)建、設(shè)置、用來發(fā)送和接收數(shù)據(jù),最后會(huì)被關(guān)閉。2021/3/911WORD類型、類型、MAKEWORD、LOBYTE和和HIBYTE宏宏 WORD類型是一個(gè)16位的無符號(hào)整型,在WTYPES.H中被定義為: typedefunsignedshortWORD; 目的是提供兩個(gè)字節(jié)的存儲(chǔ),在Socket中這兩個(gè)字節(jié)可以表示主版本號(hào)和副版本號(hào)。 使用MAKEWORD宏可以給一個(gè)WORD類型賦值。例如要表示主版本號(hào)2,副版本號(hào)0,可以使用以下代碼: WORDwVersionRequested; wVersionRequested=M
8、AKEWORD(2,0); 注意低位內(nèi)存存儲(chǔ)主版本號(hào)2,高位內(nèi)存存儲(chǔ)副版本號(hào)0,其值為0 x0002。使用宏LOBYTE可以讀取WORD的低位字節(jié),HIBYTE可以讀取高位字節(jié)。2021/3/912WSADATA類型和類型和LPWSADATA類型類型 WSADATA類型是一個(gè)結(jié)構(gòu),描述了Socket庫的一些相關(guān)信息,其結(jié)構(gòu)定義如下: typedefstructWSAData WORDwVersion; WORDwHighVersion; charszDescriptionWSADESCRIPTION_LEN+1; charszSystemStatusWSASYS_STATUS_LEN+1; u
9、nsignedshortiMaxSockets; unsignedshortiMaxUdpDg; charFAR*lpVendorInfo; WSADATA; typedefWSADATAFAR*LPWSADATA;2021/3/913WSAStartup函數(shù)函數(shù) WSAStartup函數(shù)被用來初始化Socket環(huán)境,它的定義如下: intPASCALFARWSAStartup(WORDwVersionRequired,LPWSADATAlpWSAData); 其返回值為整型,調(diào)用方式為PASCAL(即標(biāo)準(zhǔn)類型,PASCAL等于_stdcall),參數(shù)有兩個(gè),第一個(gè)參數(shù)為WORD類型,指明了S
10、ocket的版本號(hào),第二個(gè)參數(shù)為WSADATA類型的指針。 若返回值為0,則初始化成功,若不為0則失敗。2021/3/914WSACleanup函數(shù)函數(shù) 這是Socket環(huán)境的退出函數(shù)。返回值為0表示成功,SOCKET_ERROR表示失敗。2021/3/915socket函數(shù)函數(shù) socket的創(chuàng)建函數(shù),其定義為: SOCKETPASCALFARsocket(intaf,inttype,intprotocol); 第一個(gè)參數(shù)為intaf,代表網(wǎng)絡(luò)地址族,目前只有一種取值是有效的,即AF_INET,代表internet地址族; 第二個(gè)參數(shù)為inttype,代表網(wǎng)絡(luò)協(xié)議類型,SOCK_DGRAM代
11、表UDP協(xié)議,SOCK_STREAM代表TCP協(xié)議; 第三個(gè)參數(shù)為intprotocol,指定網(wǎng)絡(luò)地址族的特殊協(xié)議,目前無用,賦值0即可。 返回值為SOCKET,若返回INVALID_SOCKET則失敗。2021/3/916setsockopt函數(shù)函數(shù) 函數(shù)用來設(shè)置Socket的屬性,若不能正確設(shè)置socket屬性,則數(shù)據(jù)的發(fā)送和接收會(huì)失敗。定義如下: intPASCALFARsetsockopt(SOCKETs,intlevel,intoptname, constcharFAR*optval,intoptlen); 其返回值為int類型,0代表成功,SOCKET_ERROR代表有錯(cuò)誤發(fā)生。
12、第一個(gè)參數(shù)SOCKETs,代表要設(shè)置的套接字; 第二個(gè)參數(shù)intlevel,代表要設(shè)置的屬性所處的層次,層次包含以下取值:SOL_SOCKET代表套接字層次;IPPROTO_TCP代表TCP協(xié)議層次,IPPROTO_IP代表IP協(xié)議層次(后面兩個(gè)我都沒有用過); 第三個(gè)參數(shù)intoptname,代表設(shè)置參數(shù)的名稱,SO_BROADCAST代表允許發(fā)送廣播數(shù)據(jù)的屬性,其它屬性可參考MSDN; 第四個(gè)參數(shù)constcharFAR*optval,代表指向存儲(chǔ)參數(shù)數(shù)值的指針,注意這里可能要使用reinterpret_cast類型轉(zhuǎn)換; 第五個(gè)參數(shù)intoptlen,代表存儲(chǔ)參數(shù)數(shù)值變量的長度。2021
13、/3/917sockaddr_in sockaddr_in定義了socket發(fā)送和接收數(shù)據(jù)包的地址,定義: structsockaddr_in shortsin_family; u_shortsin_port; structin_addrsin_addr; charsin_zero8; ;2021/3/918in_addr類型類型 in_addr的定義如下: structin_addr union structu_chars_b1,s_b2,s_b3,s_b4;S_un_b; structu_shorts_w1,s_w2;S_un_w; u_longS_addr; S_un; 首先闡述in_a
14、ddr的含義,很顯然它是一個(gè)存儲(chǔ)ip地址的聯(lián)合體(忘記union含義的請看c+書),有三種表達(dá)方式: 第一種用四個(gè)字節(jié)來表示IP地址的四個(gè)數(shù)字; 第二種用兩個(gè)雙字節(jié)來表示IP地址; 第三種用一個(gè)長整型來表示IP地址。2021/3/919inet_addr 給in_addr賦值的一種最簡單方法是使用inet_addr函數(shù),它可以把一個(gè)代表IP地址的字符串賦值轉(zhuǎn)換為in_addr類型,如 addrto.sin_addr.s_addr=inet_addr(); sockaddr_in的含義比in_addr的含義要廣泛,其各個(gè)字段的含義和取值如下: 第一個(gè)字段shortsin_f
15、amily,代表網(wǎng)絡(luò)地址族,如前所述,只能取值A(chǔ)F_INET; 第二個(gè)字段u_shortsin_port,代表IP地址端口,由程序員指定; 第三個(gè)字段structin_addrsin_addr,代表IP地址; 第四個(gè)字段charsin_zero8,是為了保證sockaddr_in與SOCKADDR類型的長度相等而填充進(jìn)來的字段2021/3/920inet_ntoa函數(shù)函數(shù) 函數(shù)是inet_ntoa,可以把一個(gè)in_addr類型轉(zhuǎn)換為一個(gè)字符串2021/3/921sockaddr類型類型 sockaddr類型是用來表示Socket地址的類型,同上面的sockaddr_in類型相比,sockadd
16、r的適用范圍更廣,因?yàn)閟ockaddr_in只適用于TCP/IP地址。 Sockaddr的定義如下: structsockaddr u_shortsa_family; charsa_data14; ; 可知sockaddr有16個(gè)字節(jié),而sockaddr_in也有16個(gè)字節(jié),所以sockaddr_in是可以強(qiáng)制類型轉(zhuǎn)換為sockaddr的。事實(shí)上也往往使用這種方法。2021/3/922Sleep函數(shù)函數(shù) 線程掛起函數(shù),表示線程掛起一段時(shí)間。如,Sleep(1000)表示掛起一秒。 定義于WINBASE.H頭文件中。 WINBASE.H又被包含于WINDOWS.H中,然后WINDOWS.H被WI
17、NSOCK2.H包含。2021/3/923sendto函數(shù)函數(shù) 在Socket中有兩套發(fā)送和接收函數(shù),一是sendto和recvfrom;二是send和recv。前一套在函數(shù)參數(shù)中要指明地址;而后一套需要先將套接字和一個(gè)地址綁定,然后直接發(fā)送和接收,不需綁定地址。sendto的定義如下: intPASCALFARsendto(SOCKETs,constcharFAR*buf,intlen,intflags,conststructsockaddrFAR*to,inttolen); 第一個(gè)參數(shù)就是套接字; 第二個(gè)參數(shù)是要傳送的數(shù)據(jù)指針; 第三個(gè)參數(shù)是要傳送的數(shù)據(jù)長度(字節(jié)數(shù)); 第四個(gè)參數(shù)是傳送方
18、式的標(biāo)識(shí),如果不需要特殊要求則可以設(shè)置為0,其它值請參考MSDN; 第五個(gè)參數(shù)是目標(biāo)地址,注意這里使用的是sockaddr的指針; 第六個(gè)參數(shù)是地址的長度; 返回值為整型,如果成功,則返回發(fā)送的字節(jié)數(shù),失敗則返回SOCKET_ERROR。2021/3/924WSAGetLastError函數(shù)函數(shù) 該函數(shù)用來在Socket相關(guān)API失敗后讀取錯(cuò)誤碼,根據(jù)這些錯(cuò)誤碼可以對照查出錯(cuò)誤原因2021/3/925closesocket 關(guān)閉套接字,其參數(shù)為SOCKET類型。成功返回0,失敗返回SOCKET_ERROR。2021/3/926總結(jié) 寫一個(gè)UDP發(fā)送程序的步驟如下: 1.用WSAStartup函
19、數(shù)初始化Socket環(huán)境; 2.用socket函數(shù)創(chuàng)建一個(gè)套接字; 3.用setsockopt函數(shù)設(shè)置套接字的屬性,例如設(shè)置為廣播類型;很多時(shí)候該步驟可以省略; 4.創(chuàng)建一個(gè)sockaddr_in,并指定其IP地址和端口號(hào); 5.用sendto函數(shù)向指定地址發(fā)送數(shù)據(jù),這里的目標(biāo)地址就是廣播地址;注意這里不需要綁定,即使綁定了,其地址也會(huì)被sendto中的參數(shù)覆蓋;若使用send函數(shù)則會(huì)出錯(cuò),因?yàn)閟end是面向連接的,而UDP是非連接的,只能使用sendto發(fā)送數(shù)據(jù); 6.用closesocket函數(shù)關(guān)閉套接字; 7.用WSACleanup函數(shù)關(guān)閉Socket環(huán)境。2021/3/927總結(jié) 一個(gè)
20、UDP接收程序的步驟如下,注意接收方一定要bind套接字: 1.用WSAStartup函數(shù)初始化Socket環(huán)境; 2.用socket函數(shù)創(chuàng)建一個(gè)套接字; 3.用setsockopt函數(shù)設(shè)置套接字的屬性,例如設(shè)置為廣播類型; 4.創(chuàng)建一個(gè)sockaddr_in,并指定其IP地址和端口號(hào); 5.用bind函數(shù)將套接字與接收的地址綁定起來,然后調(diào)用recvfrom函數(shù)或者recv接收數(shù)據(jù);注意這里一定要綁定,因?yàn)榻邮請?bào)文的套接字必須在網(wǎng)絡(luò)上有一個(gè)綁定的名稱才能保證正確接收數(shù)據(jù); 6.用closesocket函數(shù)關(guān)閉套接字; 7.用WSACleanup函數(shù)關(guān)閉Socket環(huán)境。2021/3/928T
21、CP TCP與UDP最大的不同之處在于TCP是一個(gè)面向連接的協(xié)議,在進(jìn)行數(shù)據(jù)收發(fā)之前TCP必須進(jìn)行連接,并且在收發(fā)的時(shí)候必須保持該連接。2021/3/929TCP 發(fā)送方的步驟如下(省略了Socket環(huán)境的初始化、關(guān)閉等內(nèi)容): 1.用socket函數(shù)創(chuàng)建一個(gè)套接字sock; 2.用bind將sock綁定到本地地址; 3.用listen偵聽sock套接字; 4.用accept函數(shù)接收客戶方的連接,返回客戶方套接字clientSocket; 5.在客戶方套接字clientSocket上使用send發(fā)送數(shù)據(jù); 6.用closesocket函數(shù)關(guān)閉套接字sock和clientSocket;2021/
22、3/930TCP 接收方的步驟如下: 1.用socket函數(shù)創(chuàng)建一個(gè)套接字sock; 2.創(chuàng)建一個(gè)指向服務(wù)方的遠(yuǎn)程地址; 3.用connect將sock連接到服務(wù)方,使用遠(yuǎn)程地址; 4.在套接字上使用recv接收數(shù)據(jù); 5.用closesocket函數(shù)關(guān)閉套接字sock;2021/3/931TCP 注意:在服務(wù)方有兩個(gè)地址,一個(gè)是本地地址myaddr,另一個(gè)是目標(biāo)地址addrto。 本地地址myaddr用來和本地套接字sock綁定,目標(biāo)地址被sock用來accept客戶方套接字clientSocket。 這樣sock和clientSocket連接成功,這兩個(gè)地址也連接上了。 在服務(wù)方使用cli
23、entSocket發(fā)送數(shù)據(jù),則會(huì)從本地地址傳送到目標(biāo)地址。 在客戶方只有一個(gè)地址,即來源地址addrfrom。這個(gè)地址被用來connect遠(yuǎn)程的服務(wù)方套接字,connect成功則本地套接字與遠(yuǎn)程的來源地址連接了,因此可以使用該套接字接收遠(yuǎn)程數(shù)據(jù)。2021/3/932bind函數(shù)函數(shù) bind函數(shù)用來將一個(gè)套接字綁定到一個(gè)IP地址。一般只在服務(wù)方(即數(shù)據(jù)發(fā)送方)調(diào)用,很多函數(shù)會(huì)隱式的調(diào)用bind函數(shù)。2021/3/933listen函數(shù)函數(shù) 從服務(wù)方監(jiān)聽客戶方的連接。同一個(gè)套接字可以多次監(jiān)聽。2021/3/934connect和和accept函數(shù)函數(shù) connect是客戶方連接服務(wù)方的函數(shù),而a
24、ccept是服務(wù)方同意客戶方連接的函數(shù)。 這兩個(gè)配套函數(shù)分別在各自的程序中被成功調(diào)用后就可以收發(fā)數(shù)據(jù)了。2021/3/935send和和recv函數(shù)函數(shù) send和recv是用來發(fā)送和接收數(shù)據(jù)的兩個(gè)重要函數(shù)。 send只能在已經(jīng)連接的狀態(tài)下使用,而recv可以面向連接和非連接的狀態(tài)下使用。 send的定義如下: intWSAAPIsend( SOCKETs, constcharFAR*buf, intlen, intflags ); 其參數(shù)的含義和sendto中的前四個(gè)參數(shù)一樣。 而recv的定義如下: intWSAAPIrecv( SOCKETs, charFAR*buf, intlen,
25、intflags ); 其參數(shù)含義與send中的參數(shù)含義一樣。2021/3/936一個(gè)局域網(wǎng)聊天工具的編寫一個(gè)局域網(wǎng)聊天工具的編寫 能設(shè)計(jì)如下: 1.要能夠指定聊天對象的IP和端口(端口可以內(nèi)部確定); 2.要能夠發(fā)送消息給指定聊天對象; 3.要能夠接收聊天對象的消息; 4.接收消息時(shí)要播放聲音; 5.接收消息時(shí)如果當(dāng)前對話框不是最前端,要閃動(dòng)圖標(biāo); 6.要有托盤圖標(biāo),可以將對話框收入托盤;2021/3/937功能實(shí)現(xiàn)功能實(shí)現(xiàn) 將內(nèi)部端口設(shè)為5556,提供一個(gè)IP地址控件來設(shè)置聊天對象的IP。該控件必須能夠讀取IP地址并賦值給內(nèi)部變量。將地址轉(zhuǎn)換為in_addr類型。 發(fā)送消息需要使用一個(gè)套接
26、字。 接收消息也需要使用一個(gè)套接字,由于發(fā)送消息也使用了一個(gè)套接字,為了在同一個(gè)進(jìn)程中同時(shí)發(fā)送和接收消息,需要使用多線程技術(shù),將發(fā)送消息的線程設(shè)為主線程;而接收消息的線程設(shè)為子線程,子線程只負(fù)責(zé)接收UDP消息,在收到消息后顯示到主界面中。 接收消息時(shí)播放聲音這個(gè)功能在子線程中完成,使用sndPlaySound函數(shù),并提供一個(gè)wav文件即可。 閃動(dòng)圖標(biāo)功能需要使用一個(gè)Timer,在主對話框類中添加一個(gè)OnTimer函數(shù),定時(shí)檢查當(dāng)前窗口狀態(tài)變量是否為假,若為假就每次設(shè)置另一個(gè)圖標(biāo)。若當(dāng)前窗口顯示到最頂端,則設(shè)置為默認(rèn)圖標(biāo)。 托盤圖標(biāo)功能用網(wǎng)上下載的CtrayIcon類。需要提供一個(gè)自定義消息,一
27、個(gè)彈出菜單資源。2021/3/938所需資源所需資源 頭文件:winsock2.h,Mmsystem.h 庫文件:ws2_32.lib,winmm.lib dll:Ws2_32.dll,winmm.dll wav文件:recv.wav 圖標(biāo):一個(gè)主程序圖標(biāo)IDI_MAIN、四個(gè)變化圖標(biāo)IDI_ICON14; 菜單:一個(gè)給托盤用的彈出菜單IDR_TRAYICON; 說明,Mmsystem.h和winmm.lib、winmm.dll是為了那個(gè)播放聲音的功能。2021/3/939托盤功能托盤功能 托盤屬于界面功能,是變更很少的需求,因此首先完成。 1.引入TRAYICON.H和TRAYICON.cp
28、p兩個(gè)類; 2.在CLANTalkDlg類中加入一個(gè)CTrayIconm_trayIcon;屬性; 3.在CLANTalkDlg的構(gòu)造函數(shù)中初始化m_trayIcon,m_trayIcon(IDR_TRAYICON); 4.添加一個(gè)自定義消息WM_MY_TRAY_NOTIFICATION,即在三個(gè)地方添加消息定義、消息響應(yīng)函數(shù)、消息映射; 5.在InitDialog方法中調(diào)用托盤初始化的兩個(gè)函數(shù)m_trayIcon.SetNotificationWnd(this,WM_MY_TRAY_NOTIFICATION);m_trayIcon.SetIcon(IDI_MAIN); 6.重寫OnClose
29、方法,添加彈出菜單的OnAppSuspend和OnAppOpen以及OnAppAbout方法; 7.重寫對話框的OnCancel方法。2021/3/940動(dòng)態(tài)圖標(biāo)動(dòng)態(tài)圖標(biāo) 動(dòng)態(tài)圖標(biāo)也是界面相關(guān)功能,首先完成。 1.添加四個(gè)HICON變量m_hIcon1,m_hIcon2,m_hIcon3,m_hIcon4; 2.在構(gòu)造函數(shù)中初始化這四個(gè)變量m_hIcon1=AfxGetApp()-LoadIcon(IDI_ICON1); 3.在InitDialog中設(shè)置調(diào)用SetTimer(1,300,NULL);設(shè)置一個(gè)timer,id為1,間隔為300微秒; 4.添加一個(gè)布爾屬性m_bDynamicIco
30、n,指示目前是否需要?jiǎng)討B(tài)圖標(biāo),并給出一個(gè)設(shè)置函數(shù)SetDynamicIcon; 5.添加一個(gè)OnTimer函數(shù),讓每次timer調(diào)用時(shí)根據(jù)m_bDynamicIcon的值修改圖標(biāo); 兩個(gè)地方是用來設(shè)置動(dòng)態(tài)圖標(biāo)的,一個(gè)是當(dāng)程序收到消息并且程序不在桌面頂端時(shí),這時(shí)設(shè)置為動(dòng)態(tài)圖標(biāo),在后面的消息接收線程中處理;二是當(dāng)程序顯示到桌面頂端時(shí),設(shè)置為非動(dòng)態(tài); 重載OnActivate方法可以完成第二個(gè)時(shí)刻的要求。當(dāng)窗口狀態(tài)為WA_ACTIVE或者WA_CLICKACTIVE時(shí)SetDynamicIcon(false),否則設(shè)置SetDynamicIcon(true);2021/3/941發(fā)送發(fā)送UDP報(bào)文功
31、能報(bào)文功能 發(fā)送UDP報(bào)文只需在主線程中完成,需要以下步驟: 1.初始化Socket環(huán)境,這可以在CLANTalkApp的InitInstance中完成,同理關(guān)閉Socket環(huán)境在ExitInstance中完成;我們可以使用前面的方法,也可以直接調(diào)用MFC中的AfxSocketInit函數(shù),這個(gè)函數(shù)可以確保在程序結(jié)束時(shí)自動(dòng)關(guān)閉Socket環(huán)境; 2.創(chuàng)建socket,考慮到報(bào)錯(cuò)信息需要彈出對話框,因此不在CLANTalkDlg的構(gòu)造函數(shù)中創(chuàng)建,而是在InitDialog中構(gòu)建;發(fā)送報(bào)文的socket為m_sendSock; 3.設(shè)置目的地址功能,需要一個(gè)地址賦值函數(shù)setAddress(char*szAddr);可以將一個(gè)字符串地址賦值給sockaddr_in形式
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版股份質(zhì)押回購交易合同3篇
- 二零二四二手鋼鐵材料購買與運(yùn)輸合同3篇
- 二零二五版打印機(jī)銷售渠道資源整合與共享合同3篇
- 年度聚碳酸酯(PC)及合金市場分析及競爭策略分析報(bào)告
- 二零二四年工業(yè)自動(dòng)化設(shè)備安裝與生產(chǎn)流程優(yōu)化合同3篇
- 2024-2025學(xué)年新教材高中數(shù)學(xué)第十章復(fù)數(shù)10.2.2第1課時(shí)復(fù)數(shù)的乘法教師用書教案新人教B版必修第四冊
- 二零二五年文秘與檔案管理勞動(dòng)合同2篇
- 二零二五年度網(wǎng)絡(luò)安全風(fēng)險(xiǎn)評估與防護(hù)合同3篇
- 2025年星酒店投資技術(shù)服務(wù)與酒店客房智能化改造合同3篇
- 二零二五年度特色餐飲店承包經(jīng)營權(quán)轉(zhuǎn)讓合同3篇
- 交通設(shè)施設(shè)備供貨及技術(shù)支持方案
- 美容美發(fā)店火災(zāi)應(yīng)急預(yù)案
- 餐車移動(dòng)食材配送方案
- 項(xiàng)目工程師年終總結(jié)課件
- 一年級口算練習(xí)題大全(可直接打印A4)
- 電動(dòng)車棚消防應(yīng)急預(yù)案
- 人力資源戰(zhàn)略規(guī)劃地圖
- 2023年河南公務(wù)員考試申論試題(縣級卷)
- DB35T 2198-2024 工業(yè)園區(qū)低零碳創(chuàng)建評估準(zhǔn)則 福建省市監(jiān)局
- 不為積習(xí)所蔽勿為時(shí)尚所惑-如何做一個(gè) 好老師 高中主題班會(huì)課件
- 托育服務(wù)中心項(xiàng)目可行性研究報(bào)告
評論
0/150
提交評論