




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、畢畢 業(yè)業(yè) 設(shè)設(shè) 計計( 論論 文文) 遠程控制軟件的設(shè)計與開發(fā)遠程控制軟件的設(shè)計與開發(fā) 控制遠程按鍵控制遠程按鍵 論文作者姓名:論文作者姓名: 申請學(xué)位專業(yè):申請學(xué)位專業(yè): 申請學(xué)位類別:申請學(xué)位類別: 指指導(dǎo)導(dǎo)教教師師姓姓名名(職職稱稱) : 論文提交日期:論文提交日期: 遠程控制軟件的設(shè)計與開發(fā)遠程控制軟件的設(shè)計與開發(fā) 控制遠程按鍵控制遠程按鍵 摘摘 要要 今天,許多企業(yè)和增值分銷商正在把遠程控制技術(shù)作為有效的技術(shù)支持工 具,許多網(wǎng)絡(luò)管理員都采用這類軟件對局域網(wǎng)進行遠程管理。遠程管理軟件對 于出差在外的商務(wù)人員用處非常大,這樣他們可以隨時提取自己家里計算機中 的數(shù)據(jù)和資料。本文介紹的軟件
2、用 C+語言編寫而成,能通過一臺主機控制網(wǎng) 絡(luò)上的一臺或多臺遠程主機的鍵盤。軟件采用了 C/S 模式,即客戶端/服務(wù)器端 模式??蛻舳藢Ψ?wù)器端進行監(jiān)控操作,服務(wù)器端接收客戶端傳輸?shù)臄?shù)據(jù)并進 行分析和執(zhí)行。本文首先對遠程控制軟件的原理和 WinSock 技術(shù)作了介紹,最 后闡述了如何利用 WinSock 控件與遠程計算機建立連接,實現(xiàn)控制按鍵的功能。 關(guān)鍵詞關(guān)鍵詞: 套接字;客戶端/服務(wù)器模式;遠程控制;模擬按鍵 The Design and Development of the Remote Control Software Remote Keyboard Controlling Abstr
3、act Today, many enterprises and retail traders are using the remote control techniques as an effective technique support tool, and many network administrators use such kind of software to remotely manage their LANs. Remote control software is also very useful to business persons for them to retrieve
4、 data and materials in their personal computers at home from any where and at any time. This software introduced in the paper, was written with C + language and can control the keyboards of one or many remote computers on the network. The software adopts C/S pattern (Client/Server). The client side
5、controls and operates the server, which receives the data transmitted from the client side and explains and carries out the commands. This paper first introduces the principle of the remote control software and WinSock technology, then explains how to use WinSock to connect to the remote computer,an
6、d how to implement the keyboard controlling functions. Key word: Socket; Client/Server; Remote Controlling; Simulating Keyboard Events 目目 錄錄 論文總頁數(shù):26 頁 1.引言.1 1.1 課題背景.1 1.2 國內(nèi)外研究現(xiàn)狀.1 1.3 本課題研究的意義.1 1.4 本課題的研究方法.1 2. 遠程控制概述.2 2.1 遠程控制概念.2 2.2 遠程控制與其他程序的區(qū)別.2 2.2.1 遠程控制與病毒的區(qū)別.2 2.2.2 遠程控制與黑客的區(qū)別.2 2.2.
7、3 遠程控制與木馬的區(qū)別.3 3. 控制遠程按鍵的背景技術(shù)介紹.3 3.1 WINSOCKET的介紹.3 3.1.1 Socket 的基本概念 .3 3.1.2 Winsocket.3 3.2 客戶端/服務(wù)器(C/S)模式.3 4.控制遠程按鍵程序的需求分析.4 4.1 控制遠程按鍵的需求分析 .4 4.2 控制遠程按鍵的流程分析 .4 5 遠程按鍵控制的實現(xiàn).5 5.1 使用 WINSOCKET建立控制端和被控制端連接 .5 5.1.1 初始化 Winsock .5 5.1.2 創(chuàng)建套接字.6 5.1.3 指定本地地址.7 5.1.4 建立套接字連接.7 5.1.5 監(jiān)聽連接.9 5.1.6
8、 關(guān)閉套接字.9 5.2 按鍵事件處理.9 5.2.1 數(shù)據(jù)傳輸.9 5.2.2 模擬按鍵.10 5.3 具體代碼 .10 結(jié) 論.23 參考文獻.24 致 謝.25 聲 明.26 1.1.引言引言 1.11.1 課題背景課題背景 我們知道,通常企業(yè)內(nèi)部或者 IT 公司的客戶技術(shù)支持部門都有技術(shù)支持業(yè) 務(wù),其任務(wù)是通過電話解答疑難問題,努力減少技術(shù)人員到現(xiàn)場服務(wù)或者讓用 戶把設(shè)備送到支持中心進行維護。這種技術(shù)支持方式盡管被普遍采用,但效率 不高而且大大增加了技術(shù)支持成本。 通常,技術(shù)支持必須依賴技術(shù) 人員和用戶之間的口頭交流來進行,這種交流既耗時又容易出錯。許多商業(yè)用 戶對計算機知之甚少,然而
9、當(dāng)遇到問題時,他們必須向技術(shù)人員提供故障情報 及相關(guān)操作。在嘗試解決問題時,技術(shù)人員可能指導(dǎo)用戶執(zhí)行一系列復(fù)雜的過 程,而這些過程對用戶來說或許完全不熟悉;如果用戶不能正確的按要求操作, 反而使問題惡化。此外,如果通過電話不能解決問題,那么技術(shù)人員親自到用 戶現(xiàn)場解決問題之前,計算機將一自不能使用。 遠程控制軟件能使技術(shù)人員直接操作遠程計算機,就像操作本地機器一樣, 無須用戶介入,技術(shù)人員技能得到該機器的問題的第一手材料,從而加快了問 題的解決。實際上,使用遠程控制工具的技術(shù)人員能夠做到解答疑難問題,安 裝和配置軟件,把軟件下載到用戶計算機上,配置應(yīng)用程序和系統(tǒng)軟件設(shè)置并 可通過實際操作培訓(xùn)用
10、戶。 1.21.2 國內(nèi)外研究現(xiàn)狀國內(nèi)外研究現(xiàn)狀 根據(jù) IDC 統(tǒng)計,美國遠程控制軟件市場從 1998 年的 6.77 億美元發(fā)展到 2002 年的 19 億美元,年增長率達 31.5%,是軟件技術(shù)支持消費中第 3 個增長最 快的領(lǐng)域。 國內(nèi)的遠程控制軟件發(fā)展也比較樂觀,出現(xiàn)了許多優(yōu)秀的軟件,比如大家 都比較熟悉的“冰河” , “灰鴿子”等。 1.31.3 本課題研究的意義本課題研究的意義 遠程控制軟件已經(jīng)使用很多年了,起初是為了讓 PC 用戶在離開辦公室的時 候能訪問其臺式 PC 硬盤中的信息,甚至可以通過其臺式 PC 訪問企業(yè)網(wǎng)絡(luò)資源。 今天,許多企業(yè)和增值分銷商正在把遠程控制能力作為有效
11、的技術(shù)支持工具。 許多網(wǎng)絡(luò)管理員都采用這類軟件對局域網(wǎng)進行管理或者在自己家更新自己網(wǎng)站 的內(nèi)容。這類軟件對于出差在外的商務(wù)人員用處非常大,這樣他們可以隨時提 取自己家里計算機中的數(shù)據(jù)和資料。 1.41.4 本課題的研究方法本課題的研究方法 本軟件用 C+語言編寫,采用的是 C/S 結(jié)構(gòu),一個客戶端,一個服務(wù)器端。 客戶端是控制端,服務(wù)器端是被控制端。主要功能就是通過本地計算機,控制 遠程另一臺計算機的鍵盤。主要思路是先用 Winsocket 建立兩邊的連接,客戶端 向服務(wù)器端發(fā)送鍵碼,服務(wù)器端得到鍵碼后模擬出按鍵事件。 2.2. 遠程控制概述遠程控制概述 2.12.1 遠程控制概念遠程控制概念
12、 對于遠程控制軟件的定義有很多種。我們認(rèn)為,遠程控制指管理人員在異 地通過計算機網(wǎng)絡(luò)(WAN) ,異地?fù)芴柣螂p方都接入 Internet 等手段,連接目標(biāo) 計算機,通過本地計算機對遠程計算機進行管理和維護的行為。 遠程控制軟件實際上是一種客戶機/服務(wù)器程序,服務(wù)器程序安放在被控制 的計算機端,客戶機安裝在控制端。在客戶端和服務(wù)器端都安裝成功之后,客 戶端在網(wǎng)絡(luò)上搜尋已經(jīng)安裝了服務(wù)器的遠程計算機;然后,客戶端就發(fā)指令獲 得服務(wù)器端的連接指令,兩臺 PC 建立起連接,就可以通過網(wǎng)絡(luò)的互連協(xié)議 TCP/IP 進行遠端控制。 遠程控制的原理很簡單:在本機上直接啟動運行的程序,擁有與使用者 (客戶端)相
13、同的權(quán)限。因此如果能夠啟動服務(wù)器端的服務(wù)程序,就可以使用 相應(yīng)的客戶端程序直接控制主機了。也就是說客戶端就好比一個超級用戶,可 以直接控制計算機。 2.22.2 遠程控制與其他程序的區(qū)別遠程控制與其他程序的區(qū)別 遠程控制軟件可以為我們的網(wǎng)絡(luò)管理工作做很多工作,以保證網(wǎng)絡(luò)和計算 機操作系統(tǒng)的安全。這類程序的監(jiān)聽功能,也是為了保證網(wǎng)絡(luò)的安全而設(shè)計的, 但是如果使用不當(dāng)?shù)脑?,就會出現(xiàn)很多的問題。為了達到遠程控制的目的,就 必須將這些軟件隱蔽起來。例如有的遠程控制軟件為了不讓用戶發(fā)現(xiàn)而被刪除, 就采用了一些辦法讓自己隱蔽起來,使遠程控制程序本身附著在某些 Windows 程序上,以增強駐留系統(tǒng)的可靠性
14、。然而,正是由于這種功能,才使遠程控制 軟件變得可怕起來,也使遠程控制軟件,病毒和黑客程序之間的區(qū)別變得越來 越模糊。 2.2.12.2.1 遠程控制與病毒的區(qū)別遠程控制與病毒的區(qū)別 計算機病毒是能通過某種途徑潛伏在計算機存儲介質(zhì)(或程序)里,當(dāng)達 到某種條件時即被激活的具有對計算機資源進行破壞作用的一種程序或指令集 合。計算機病毒一般具有破壞性,隱蔽性,潛伏性,傳染性等特點。從計算機 病毒的定義和特征中可以看出,遠程控制軟件與病毒的區(qū)別是十分明顯的。最 基本的區(qū)別就在于病毒有很強的傳染性,而遠程控制軟件沒有。但是,如果遠 程控制軟件沒有好的處理好軟件的安全問題,就會跟病毒相差無幾了。 2.2
15、.22.2.2 遠程控制與黑客的區(qū)別遠程控制與黑客的區(qū)別 “黑客”一詞來源于英語單詞 hack,本指“手法巧妙,技術(shù)高明的惡作劇” 。今天,在最新和最普遍的意思上說, “黑客”意味著那些偷偷地,未經(jīng)許可就 進入別人計算機系統(tǒng)的計算機犯罪。他們或修改網(wǎng)頁搞惡作劇或散布流言進行 恐嚇,或破壞系統(tǒng)程度,施放病毒使系統(tǒng)險入癱瘓,或竊取政治,軍事與商業(yè) 機密,或進行電子郵件騷擾,或轉(zhuǎn)移資金帳戶,竊取錢財,真所謂作案方式多 樣,花樣翻新,令人防不勝防。 由此可見,遠程控制與黑客的區(qū)別是較大的。黑客往往利用操作系統(tǒng)和網(wǎng) 絡(luò)的漏洞進行破壞活動,而遠程控制軟件的一大任務(wù)就是要保護控制端計算機, 使之不受非授權(quán)用
16、戶的訪問。 當(dāng)然,如果編寫遠程控制軟件的唯一目的就是為了盜竊人家計算機上的隱 私,這樣的遠程控制軟件就不再是有用的軟件而是惡性的黑客程序了。 2.2.32.2.3 遠程控制與木馬的區(qū)別遠程控制與木馬的區(qū)別 木馬是一種在遠程計算機之間建立起連接,使遠程計算機能夠通過網(wǎng)絡(luò)控 制本地計算機的程序。它的運行遵循 TCP/IP 協(xié)議。由于它像間諜一樣潛入用戶 的電腦,為其他人的攻擊打開后門,與戰(zhàn)爭的“木馬”戰(zhàn)術(shù)十分相識,因而得 名木馬程序。 木馬與遠程控制軟件的最大區(qū)別就是木馬具有隱蔽性而遠程控制軟件沒有。 3.3. 控制遠程按鍵的背景技術(shù)介紹控制遠程按鍵的背景技術(shù)介紹 3.1 Winsocket 的介
17、紹的介紹 3.1.13.1.1 SocketSocket 的基本概念的基本概念 實際上,Socket 在計算機中提供了一個通信端口(套接口) 。通過這個端 口,一臺計算機可以與任何一臺具有 Socket 接口的計算機通信。通信的基礎(chǔ)是 套接口,一個套接口是通信的一端,在這一端上可以找到與其對應(yīng)的一個名字。 一個正在被使用的套接口都有他的類型和與其相關(guān)的進程,套接口存在于通信 域中。一個套接口通常和同一個域中的套接口交換數(shù)據(jù)(數(shù)據(jù)交換也可以穿越 域的界限,但這時一定要執(zhí)行某種解釋程序) 。應(yīng)用程序在網(wǎng)絡(luò)上傳輸,接收的 信息都通過這個套接口來實現(xiàn)。在應(yīng)用開發(fā)中就像使用文件句柄一樣,可以對 Sock
18、et 句柄進行讀寫操作。 3.1.23.1.2 WinsocketWinsocket windows Socket(WinSock)API 是基于 BSD 版本的套接字,但只為 Windows 進行了專門的擴展。此外,WinSock2.0 能支持許多網(wǎng)絡(luò)協(xié)議,包括 TCP/IP,DEC Net 和 Novell 的 IPX/SPX 等。Windows 套接字規(guī)范是一個由幾家 開發(fā)商支持的接口規(guī)范。每個開發(fā)商都提供了他們自己的 DLL 來和傳輸棧一起 工作。 3.23.2 客戶端客戶端/ /服務(wù)器(服務(wù)器(C/SC/S)模式)模式 在 TCP/IP 網(wǎng)絡(luò)應(yīng)用中,通信的兩個進程間相互作用的主要模式
19、是客戶機/ 服務(wù)器模式(Client/Server) 。即客戶向服務(wù)器發(fā)出服務(wù)請求,服務(wù)器接收到 請求后,提供相應(yīng)的服務(wù)??蛻魴C/服務(wù)器模式的建立基于以下兩點:首先,建 立網(wǎng)絡(luò)的起因是網(wǎng)絡(luò)中軟硬件資源,運算能力和信息不均等,需要共享,從而 造就擁有眾多資源的主機提供服務(wù),資源較少的客戶請求服務(wù)這一非對等作用; 其次,網(wǎng)間進程通信完全是異步的,相互通信的進程見既不存在父子關(guān)系,又 不共享內(nèi)存緩沖區(qū),因此需要一種機制為希望通信的進程間建立聯(lián)系,為兩者 的數(shù)據(jù)交換提供同步,這就是基于客戶機/服務(wù)器模式的 TCP/IP。 4.4.控制遠程按鍵程序的需求分析控制遠程按鍵程序的需求分析 4.14.1 控制
20、遠程按鍵的需求分析控制遠程按鍵的需求分析 本程序的主要作用是控制服務(wù)器端的按鍵。當(dāng)客戶端發(fā)生鍵盤按鍵事件時, 服務(wù)器端能夠得到鍵碼,實現(xiàn)按鍵的模擬。主要由以下幾部分構(gòu)成: (1) 實現(xiàn)使用 WinSocket 建立客戶端和服務(wù)器端連接。要想實現(xiàn)遠程控 制,首先就要實現(xiàn)遠程的互連。用 WinSocket 將客戶端和服務(wù)器端連接起來后, 服務(wù)器端才可以得到控制端的信息。 (2) 控制端發(fā)送鍵碼。當(dāng)客戶端與服務(wù)器端連接好以后,客戶端要想控 制服務(wù)器端的按鍵,必須要向服務(wù)器端發(fā)送與鍵盤按鍵對應(yīng)的鍵碼,服務(wù)器端 得到了這個鍵碼后才可以做出按鍵的模擬。 (3) 實現(xiàn)服務(wù)器端模擬按鍵事件。服務(wù)器端在得到客戶
21、端傳來的鍵碼后, 根據(jù)鍵碼做出正確的按鍵模擬,實現(xiàn)控制遠程按鍵的功能。 4.2 控制遠程按鍵的流程分析控制遠程按鍵的流程分析 發(fā)送連接請求接受連接請求 等待控制命令 處理鍵盤事件 發(fā)送鍵碼和 相關(guān)事件參數(shù) 接受鍵盤事件 命令和數(shù)據(jù) 模擬鍵盤事件 Keybd_event 客客戶戶端端服服務(wù)務(wù)端端 圖 1 控制遠程按鍵流程分析圖 5 5 遠程按鍵控制的實現(xiàn)遠程按鍵控制的實現(xiàn) 5.15.1 使用使用 WinsocketWinsocket 建立控制端和被控制端連接建立控制端和被控制端連接 首先,客戶端和服務(wù)器端都要創(chuàng)建一個數(shù)據(jù)套接字。接著,服務(wù)器調(diào)用 bind()函數(shù)給套接字分配一個公認(rèn)的端口。這樣,
22、客戶端和服務(wù)器端就使用同 樣的端口來表示服務(wù)器套接字。一旦服務(wù)器將公認(rèn)端口分配給了套接字,客戶 端和服務(wù)器端就都能使用 sendto()和 recvfrom()來發(fā)送和接收數(shù)據(jù)報直到完成 傳遞。然后調(diào)用 close socket 來關(guān)閉套接字。 5.1.15.1.1 初始化初始化 WinsockWinsock WSAStartup()函數(shù)的原型聲明如下: Int WSAStartup (WORD wVersionRequested, LPWSADATA lpWSAData ); 該函數(shù)共有兩個參數(shù)。一個參數(shù)是一個 WORD(雙字節(jié))型數(shù)值,他指應(yīng)用 程序中要使用的 WinSock 規(guī)范的最高版
23、本。其中主版本在低位字節(jié),副版本號 在高位字節(jié)。第二個參數(shù)指一個指向 WSDATA 結(jié)構(gòu)的指針,該結(jié)構(gòu)的定義如下: Typedef struct WSAData WORD wVersion; WORD wHighVersion; Char szDescriptionWSADESCRIPTION_LEN+1; Char szSyestemStatusWSASYS_ STATUS_LEN+1; Unsigned short iMaxSocket; Unsigned short iMaxUdpDg; Char FAR * IpVendorInfo; WSADATA,FAR * LPWSADATA 其
24、中成員 wVersion 指 Windows Sockets 的版本號。 成員 wHighVersion 指 Windows Sockets 的最高版本。通常情況下,該成員 的取值與成員 wVersion 相同。 成員 szDescrpition 指 Windows Sockets 實現(xiàn)的句柄字符串。 成員 szSystemStatus 指 Windows Sockets 的配置信息或相關(guān)狀態(tài)。 成員 iMaxSockets,iMaxUdpDg 和 lpVendorInfo 保留;在 Windows Socket2 及以后的版本中被忽略。 我們一般采用如下代碼來調(diào)用 WSAStartup():
25、 # include /對應(yīng) winSock 2,應(yīng)該包含 winsock2.h WSADATA WSAData; If (WSAStartup(0 x0101, if(WSAData.wVersion!=0 x0101) /支持版本無效,報告后終止 return; 這時,如果 WinSock.dll 或底層網(wǎng)絡(luò)子系統(tǒng)沒有正確初始化或沒有找到, WSAtartup()將返回 WSASYSNOTREADY。此外,這個函數(shù)允許應(yīng)用程序協(xié)商使用 某種版本的 WinSock 規(guī)范。通常在調(diào)用 WSAStarup()時,我們應(yīng)該指定想使用 的 WinSock 最高版本。如果這個版本比任何 DLL 支持的
26、版本低,WSAStartup() 將返回 WSAVERNOTSUPPORTED。 如果我們要求的版本高于或等于 DLL(動態(tài)鏈接庫)所支持的版本。 WSAData 的 wVersion 成員將包含應(yīng)用程序應(yīng)該使用的版本。而 wHighVersion 成員中將包含 DLL 所支持的最高版本號。 如果返回到 wVersion 成員的版本號不能被應(yīng)用程序所接受,我們就應(yīng)該調(diào) 用 WSACleanup()并退出引用程序,或找一個不同的 WinSock32.DLL 來試一試。 當(dāng)然,這時需要動態(tài)加載新的 DLL,并從中調(diào)用 WSAStartup ()。 5.1.25.1.2 創(chuàng)建套接字創(chuàng)建套接字 任何應(yīng)
27、用程序在使用套接字之前,首先必須擁有一個套接字,系統(tǒng)調(diào)用 socket 函數(shù)向應(yīng)用程序提供創(chuàng)建套接字的手段。Socket()函數(shù)的原型聲明如下: SOCKET PASCAL FAR socket (int af,int type ,int protocol); 該函數(shù)共有 3 參數(shù),其中參數(shù) af 指定通信發(fā)生的區(qū)域。UNIX 系統(tǒng)支持的 地址簇有 AF_UNIX,AF_INET,AF_NS 等。而 DOS,Windows 中僅支持 AF_INET, 它是網(wǎng)際網(wǎng)區(qū)域。 參數(shù) type 描述建立的套接字類型。也就是指流式套接字還是數(shù)據(jù)報套接 字。 參數(shù) protocol 說明該套接字使用的特定協(xié)
28、議,如果該參數(shù)設(shè)為 0。則表示 使用默認(rèn)的連接模式。 Socket()函數(shù)根據(jù)這 3 個參數(shù)建立一個套接字,并將相應(yīng)的資源分配給它, 同時返回一個整型套接字句柄。 5.1.35.1.3 指定本地地址指定本地地址 當(dāng)一個套接字用 socket()創(chuàng)建后,存在一個名字空間(地址簇) ,但它沒 有被命名。Bind()將套接字地址(包括本地主機地址和本地端口地址)與所創(chuàng) 建的套接字編號聯(lián)系起來,即將名字賦予套接字。bind()函數(shù)的原型聲明如下: int PASCAL FAR bind (SOCKER s,const struct sockaddr FAR *name,int namelen); bi
29、nd()函數(shù)共有 3 個參數(shù),其中參數(shù) s 是由 socket()函數(shù)調(diào)用返回的并且 未作連接的套接字句柄。 參數(shù) name 是賦給套接字 s 的本地地址(名字) ,其長度可變,結(jié)構(gòu)隨通信 域的不同而不同。 參數(shù) namelen 指參數(shù) name 的長度。 如果調(diào)用成功,bind ()函數(shù)返回 0;否則,返回 SOCKER_ERROR。 地址在建立套接字通信過程中起著重要作用,作為一個網(wǎng)絡(luò)應(yīng)用程序設(shè)計 者對套接字地址結(jié)構(gòu)必須有明確的認(rèn)識。例如,UNIX BSD 有一組描述套接字地 址的數(shù)據(jù)結(jié)構(gòu),其中使用 TCP/IP 協(xié)議的地址結(jié)構(gòu)為: struct sockaddr_in short sin
30、_family; /* AF_INET*/ u_short sin_port: /*16 位端口號,網(wǎng)絡(luò)字節(jié)順 序*/ struct in_addr sin_addr; /*32 位 IP 地址,網(wǎng)絡(luò)字節(jié) 順序*/ char sin_zero8; /*保留*/ 5.1.45.1.4 建立套接字連接建立套接字連接 建立套接字連接需要使用兩個函數(shù)。即 connect()與 accept()。這兩個函 數(shù)用于完成一個完整相關(guān)的建立,其中 connect()用于建立連接。無連接的套 接字進程也可以調(diào)用 connect(),但這時在進程之間沒有實際的報文交換,調(diào) 用將從本地操作系統(tǒng)直接返回。這樣做的優(yōu)點
31、是程序員不必為每一數(shù)據(jù)指定目 的地址,而且如果收到一個數(shù)據(jù)報,其目的端口未與任何套接字建立“連接” , 便能判斷該端口不可操作。Accept()用于使服務(wù)器等待來自某客戶進程的實際 連接。 Connect()函數(shù)的原型聲明如下: int PASCAL FAR connect(SOCKER s,const struct sockaddr FAR *name,int namelen); Connect()函數(shù)共有 3 個參數(shù),其中參數(shù) s 指要建立連接的本地套接字句柄。 參數(shù) name 指對方套接字地址結(jié)構(gòu)的指針,對方套接字地址長度由參數(shù) namelen 說明。 如果調(diào)用成功,connect()函
32、數(shù)返回 0;否則,返回 SOCKET_ERROR。在面向 連接的協(xié)議中,該函數(shù)調(diào)用導(dǎo)致本地系統(tǒng)和外部系統(tǒng)之間連接的實際建立。 由于地址簇總被包含在套接字地址結(jié)構(gòu)的前兩個字節(jié)中,并通過 socket() 函數(shù)調(diào)用某個協(xié)議簇相關(guān)。因此 bind()和 connect()不需要協(xié)議作為參數(shù)。 Accept()函數(shù)的原型聲明如下: SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR* addr,int FAR*addrlen); 該函數(shù)也有 3 個參數(shù),其中參數(shù) s 為本地套接字句柄,在用做 accept()函 數(shù)調(diào)用的參數(shù)前應(yīng)該先調(diào)用 list
33、en()。 參數(shù) addr 是指向客戶方套接字地址結(jié)構(gòu)的指針,用來接收連接實體的地址。 Addr 的確切格式由套接字創(chuàng)建時建立的地址簇決定。 參數(shù) addlen 為客戶方套接字地址的長度(字節(jié)數(shù)) 。 如果調(diào)用成功,accept()函數(shù)返回一個 SOCKET 類型的值,表示接收到的套 接字的句柄;否則,返回 INVALID_SOCKET。 Accept()用于面向連接的服務(wù)。參數(shù) addr 和 addrlen 存放客戶方的地址信 息。調(diào)用前,參數(shù) addr 指向一個初值為空的地址結(jié)構(gòu),而 addrlen 的初始值為 0;調(diào)用 accepet()函數(shù)后,服務(wù)器等待從編號為 s 的套接字上接受客戶
34、連接的 請求,而連接請求是由客戶方的 connect()調(diào)用發(fā)出的。當(dāng)有連接請求到達時, accept()調(diào)用將請求連接隊列上的第一個客戶方套接字地址及長度放入 addr 和 addrlen,并創(chuàng)建一個與 s 有相同性質(zhì)的新套接字號。新的套接字可用于處理 服務(wù)器并發(fā)請求。 Socket(),bind(),connect(),accept()這 4 個套接字系統(tǒng)調(diào)用可以完成一 個完整五元通信(協(xié)議,本地主機地址和端口號,目的地址和端口號)相關(guān)的 建立。Socket()指定五元組中的協(xié)議元,它的用法與是否為客戶機或服務(wù)器, 是否面向連接無關(guān)。Bind()指定五元中的本地二元,即本地主機地址和端口號
35、, 其用法與是否面向連接有關(guān);在服務(wù)器方無論是否面向連接,均要調(diào)用 bind();在 客戶方,若采用面向連接,則可以不調(diào)用 bind(),而通過 connect()自動完成。 若采用無連接,客戶方必須使用 bind ()以獲得一個唯一的地址。 5.1.55.1.5 監(jiān)聽連接監(jiān)聽連接 建立連接之后,服務(wù)端套接字要調(diào)用 listen()函數(shù),此調(diào)用用于面向連接 服務(wù)器,表明它愿意接收連接。Listen()需在 accept()之前調(diào)用,listen () 函數(shù)的原型聲明如下: int PASCAL FAR listen(SOCKET s, int backlog); 該函數(shù)共有兩個參數(shù),其中參數(shù)
36、s 標(biāo)識一個本地已建立但尚未連接的套接 字句柄,服務(wù)器愿意從它上面接受請求。 參數(shù) backlog 表示請求連接隊列的最大長度,用于限制排隊請求的個數(shù)。 目前允許的最大值為 5。 如果調(diào)用成功,listen()函數(shù)返回零;否則,返回 SOCKET_ERROR。 Listen()在執(zhí)行調(diào)用過程中可為沒有調(diào)用過 bind()的套接字 s 完成所必需 的連接,并建立長度為 backlog 的請求連接隊列。 調(diào)用 listen()是服務(wù)器接收一個連接請求的 4 個步驟中的第 3 步。它在調(diào) 用 socket(),分配一個流套接字且調(diào)用 bind()給 s 賦予一個名字之后調(diào)用,而 且一定要在 acce
37、pt()之前調(diào)用。 5.1.65.1.6 關(guān)閉套接字關(guān)閉套接字 closesocket()關(guān)閉套接字 s,并釋放分配給該套接字的資源;如果 s 涉及 一個打開的 TCP 連接。則該連接被釋放。Closesocket()函數(shù)的原型聲明如下: BOOL PASCAL FAR closesocket(socker s); 該函數(shù)只有一個參數(shù) s,它指待關(guān)閉的套接字句柄。 如果調(diào)用成功,closesoker()返回零;否則,返回 SOCKET_ERROR。 5.2 按鍵事件處理按鍵事件處理 5.2.15.2.1 數(shù)據(jù)傳輸數(shù)據(jù)傳輸 當(dāng)一個連接建立好以后,就可以傳輸數(shù)據(jù)了,常用的函數(shù)調(diào)用有 send()和
38、 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ù)也有 4 個參數(shù),其中參數(shù) s 為已連接的套接字句柄。 參數(shù) buf 指向接收輸入數(shù)據(jù)緩沖區(qū)的指針,其長度由 len 指定。 參數(shù) flags 指定傳輸控制方式,如是否接收帶外數(shù)據(jù)等。 如果調(diào)用成功,recv()函數(shù)返回總共接收的字節(jié)數(shù);如果連接被關(guān)閉,返 回零。否則,返回 SOCKET ERROR。 為了從套接字中接受數(shù)據(jù),可以使用 r
39、ecv()函數(shù)。其函數(shù)原型聲明如下: int recv (SOCKET s, char FAR * buf , int len,int falgs): recv()函數(shù)有 4 個參數(shù),其中參數(shù) s 指套接字句柄。 參數(shù) buf 和 len 分別指將要接收數(shù)據(jù)的緩沖區(qū)及緩沖區(qū)長度。 參數(shù) flags 可被設(shè)置成 MSG-OOB,用來接收帶外數(shù)據(jù),或設(shè)置成 MSG-PEEK 用來向緩沖區(qū)填入收到的數(shù)據(jù),而且仍按照數(shù)據(jù)的輸入順序進行填充。 對套接字來說,如果數(shù)據(jù)是按輸入的隊列接收過來的,recv()函數(shù)將返回 讀入數(shù)據(jù)的字節(jié)數(shù),否則,recv()將返回 SOCKETERROR。 5.2.25.2.2
40、 模擬按鍵模擬按鍵 函數(shù) keybd_event()綜合一個按鍵事件,系統(tǒng)用這個事件產(chǎn)生 WM_KEYUP 或 WM_KEYDOWN 消息.在 WindowsNT 下,該函數(shù)被 SendInput()所代替.函數(shù) keybd_event()的原型如下: VOID keybd_event(BYTE bVk,BYTE bScan,DWORD dwFlags,DWORD dwExtraInfo); 函數(shù) keybd_event()有4個參數(shù),其中參數(shù) bVk 指所按鍵的虛擬鍵值.取值范 圍在1至254之間。常見的特殊鍵值有:Tab(9),Shift(16),Ctrl(17),Alt(18), Cap
41、sLock(20),Esc(27), Win(91,92),NumLock(144)及 ScrollLock(145)等. 參數(shù) bScan 指所按鍵的掃描碼。 參數(shù) dwFlags 指函數(shù)操作標(biāo)志位集合,應(yīng)用程序可以檢測這個值。它可以 取以下值。 KEYEVENTF_EXTENDEDKEY:如果指定該值,則鍵盤掃描碼加一個前綴(224) 。 KEYEVENTF_KEYUP:如果指定該值,則鍵釋放,否則,鍵一直被按下。 參數(shù) dwExtralnfo 指向一個附加的與鍵值有關(guān)聯(lián)的 32 位值。 5.35.3 具體代碼具體代碼 由于篇幅有限,這里只列出了部分重要代碼。 服務(wù)器端套接字的創(chuàng)建,綁定,
42、連接:服務(wù)器端套接字的創(chuàng)建,綁定,連接: char chName256; sockaddr_in addr; hostent* pEnt = NULL; int addrlen = 0, nRet = 0; nRet = :gethostname(chName, 256); if(nRet = 0) m_sckServer = socket(AF_INET, SOCK_STREAM, 0); if(m_sckServer != INVALID_SOCKET) pEnt = :gethostbyname(chName); if(pEnt) addr.sin_family = AF_INET; a
43、ddr.sin_port = htons(m_uPort); addr.sin_addr.s_addr = INADDR_ANY; nRet = :bind(m_sckServer, (sockaddr*) if(nRet != SOCKET_ERROR) nRet = :listen(m_sckServer, SOMAXCONN); if(nRet != SOCKET_ERROR) addrlen = sizeof(addr); TRACE(_T(開始了服務(wù),等待客戶.n); m_sckClient0 = :accept(m_sckServer, (sockaddr*) if(m_sckCl
44、ient0 != INVALID_SOCKET) /為了同步 :PL_SendSocketData(m_sckClient0, NULL, 0, PL_TEMP, MSG_OOB); m_sckClient1 = :accept(m_sckServer, (sockaddr*) if(m_sckClient0 != INVALID_SOCKET 服務(wù)器端關(guān)閉套接字:服務(wù)器端關(guān)閉套接字: BOOL CSocketThread:ExitServer() TRACE(_T(退出服務(wù),重新等待連接.n); if(g_pSendDIBThread != NULL) :TerminateThread(g_
45、pSendDIBThread-m_hThread, 0); :WaitForSingleObject(g_pSendDIBThread-m_hThread, INFINITE); g_pSendDIBThread = NULL; if(g_pWaitCommandThread != NULL) :TerminateThread(g_pWaitCommandThread-m_hThread, 0); :WaitForSingleObject(g_pWaitCommandThread-m_hThread, INFINITE); g_pWaitCommandThread = NULL; if(m_s
46、ckClient0 != INVALID_SOCKET) :closesocket(m_sckClient0); if(m_sckClient1 != INVALID_SOCKET) :closesocket(m_sckClient1); if(m_sckServer != INVALID_SOCKET) :closesocket(m_sckServer); m_sckClient0 = INVALID_SOCKET; m_sckClient1 = INVALID_SOCKET; m_sckServer = INVALID_SOCKET; return TRUE; 服務(wù)器端接收客戶端發(fā)送的指令
47、:服務(wù)器端接收客戶端發(fā)送的指令: int WINAPI PL_ReadSocketData(SOCKET s, BYTE *chData, int nLen, BYTE *chFlag, UINT uFlag) int nRet = INVALID_SOCKET; if(s != INVALID_SOCKET) nRet = :recv(s, (char *)chData, nLen, uFlag); if(nRet 0) if(chFlag != NULL) *chFlag = chData0; return nRet; 服務(wù)器端處理指令:服務(wù)器端處理指令: int CSocketThrea
48、d:Run() g_pSendInfoThread=AfxBeginThread(SendInfoThread,NULL,THREAD_PRIORITY_IDLE); while(1) if(CreateServer() BYTE *chData = new BYTEPL_SOCKET_MAXBYTES+1; while(1) ZeroMemory(chData, PL_SOCKET_MAXBYTES+1); Int nRet=:PL_ReadSocketData(m_sckClient0, chData, PL_SOCKET_MAXBYTES, NULL); if(nRet != SOCKE
49、T_ERROR) / 處理命令 nRet = DoReceive(chData, nRet); else TRACE(_T(接收數(shù)據(jù)錯誤,客戶已經(jīng)斷開了.n); break ; delete chData; chData = NULL; ExitServer(); return ExitInstance(); int CSocketThread:DoReceive(BYTE *chData, int nLen) int nRet = 0; switch(chData0)/第一個字符為命令 case PL_PEEPER_VER:/取服務(wù)端版本 char chTemp15; ZeroMemory(
50、chTemp, 15); sprintf(chTemp, %s, PEEPER_SERVER_VER_15); :PL_SendSocketData(m_sckClient0, (BYTE *)chTemp, strlen(chTemp), PL_PEEPER_VER); break ; case PL_CLOSE_PEEPER:/關(guān)閉服務(wù),退出程序 ExitServer(); ExitThread(0); break ; case PL_CLIENT_CLOSE:/關(guān)閉連接 ExitServer(); break ; case PL_MSG:/顯示一個對話框信息,使用了線程 g_strASt
51、ring.Format(_T(%s), chData+1); if(g_pWaitCommandThread != NULL) :TerminateThread(g_pWaitCommandThread-m_hThread, 0); :WaitForSingleObject(g_pWaitCommandThread-m_hThread, INFINITE); g_pWaitCommandThread = NULL; g_pWaitCommandThread = AfxBeginThread(WaitCommandThread, (LPVOID)PL_MSG); break ; /以下是模擬按鍵
52、。以下是模擬按鍵。 case PL_KEY_DOWN:/一個鍵被按下 UINT uChar = *(UINT *)(chData+1); UINT uFlag = *(UINT *)(chData+sizeof(UINT)+1); :PL_KeyDown(uChar, uFlag); :PL_SendSocketData(m_sckClient0, NULL, 0, PL_TEMP); break ; case PL_KEY_UP:/一個鍵被彈起 UINT uChar = *(UINT *)(chData+1); UINT uFlag = *(UINT *)(chData+sizeof(UIN
53、T)+1); :PL_KeyUp(uChar, uFlag); :PL_SendSocketData(m_sckClient0, NULL, 0, PL_TEMP); break ; 客戶端端初始化套接字:客戶端端初始化套接字: BOOL WINAPI PL_InitSocket() #define MAJOR_VERSION 1 #define MINOR_VERSION 2 int nStatus = 0; WORD wMajorVersion = MAJOR_VERSION; WORD wMinorVersion = MINOR_VERSION; WORD wVersionReqd =
54、MAKEWORD(wMajorVersion, wMinorVersion); WSADATA lpmyWSAData; nStatus = :WSAStartup(wVersionReqd, if(nStatus != 0) return FALSE; 客戶端連接服務(wù)器:客戶端連接服務(wù)器: int nRet = 0; sockaddr_in addr; hostent* pEnt = NULL; /套接字的創(chuàng)建。 m_pPeeperWnd-m_sckClient0 = :socket(AF_INET, SOCK_STREAM, 0); m_pPeeperWnd-m_sckClient1 =
55、:socket(AF_INET, SOCK_STREAM, 0); TRACE(_T(Client Socket 0 and 1:%d, %d.n), m_pPeeperWnd-m_sckClient0, m_pPeeperWnd-m_sckClient1); if(m_pPeeperWnd-m_sckClient0 = INVALID_SOCKET | m_pPeeperWnd-m_sckClient1 = INVALID_SOCKET) bRet = FALSE; break ; /為套接字分配地址。 pEnt = :gethostbyname(m_pPeeperWnd-m_strIP);
56、 if(!pEnt) bRet = FALSE; break ; addr.sin_family = AF_INET; addr.sin_port = :htons(u_short)(m_pPeeperWnd-m_uPort); addr.sin_addr.S_un.S_un_b.s_b1 = pEnt-h_addr_list00; addr.sin_addr.S_un.S_un_b.s_b2 = pEnt-h_addr_list01; addr.sin_addr.S_un.S_un_b.s_b3 = pEnt-h_addr_list02; addr.sin_addr.S_un.S_un_b.
57、s_b4 = pEnt-h_addr_list03; bRet = FALSE; / default for(int i = 0; i m_sckClient0, (sockaddr*) if(nRet1 != SOCKET_ERROR) BYTE chData5; ZeroMemory(chData, 5); :PL_ReadSocketData(m_pPeeperWnd-m_sckClient0, chData, 5, NULL); else TRACE(_T(Socket Error Code = %d.n), :WSAGetLastError(); TRACE(_T(Client0 i
58、s: %s.n), (nRet1 = 0)?_T(Ok):_T(Failed.); int nRet2 = :connect(m_pPeeperWnd-m_sckClient1, (sockaddr*) if(nRet2 = SOCKET_ERROR) TRACE(_T(Socket Error Code = %d.n), :WSAGetLastError(); TRACE(_T(Client1 is: %s.n), (nRet2 = 0)?_T(Ok):_T(Failed.); if(nRet1 = SOCKET_ERROR | nRet2 = SOCKET_ERROR) Sleep(200
59、0); continue ; char chConnectInfo512; ZeroMemory(chConnectInfo, 512); int nRet = :PL_ReadSocketData(m_pPeeperWnd-m_sckClient0, (BYTE *)chConnectInfo, 512, NULL); m_pPeeperWnd-SetConnectInfo(chConnectInfo); bRet = TRUE; / Connect Ok! break ; 關(guān)閉連接:關(guān)閉連接: BOOL CPeeperWnd:ExitConnect() if(m_sckClient0 !=
60、 INVALID_SOCKET) :PL_SendSocketData(m_sckClient0, NULL, 0, PL_CLIENT_CLOSE); :closesocket(m_sckClient0); if(m_sckClient1 != INVALID_SOCKET) :closesocket(m_sckClient1); m_sckClient0 = INVALID_SOCKET; m_sckClient1 = INVALID_SOCKET; if(m_pNotifyWnd) :PostMessage(m_pNotifyWnd-GetSafeHwnd(), PL_PEEPER_NO
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 宴席酒水活動方案
- 家居年底活動方案
- 賓館活動促銷活動方案
- 小區(qū)搞笑活動方案
- 小學(xué)創(chuàng)意擺攤活動方案
- 小區(qū)電梯檢驗活動方案
- 家具促消費活動方案
- 安徽國內(nèi)活動策劃方案
- 小型俱樂部活動方案
- 宜賓東樓支部活動方案
- (完整版)標(biāo)書密封條格式word
- 《關(guān)于漢語規(guī)范化的意義探析》
- 輕金屬冶金學(xué)教學(xué)課件匯總完整版電子教案全書整套課件幻燈片(最新)
- 加強社區(qū)兩委換屆監(jiān)督工作的實施方案
- 白云區(qū)地圖廣州市白云區(qū)鄉(xiāng)鎮(zhèn)街道地圖高清矢量可填充編輯地圖PPT模板
- [湖南]5萬噸凈水廠給排水工藝全套圖紙(附170頁計算說明)
- DB33T 1203-2020 建設(shè)工程施工揚塵控制技術(shù)標(biāo)準(zhǔn)
- 用藥咨詢與安全用藥管理制度
- 外國文學(xué)名著導(dǎo)讀
- 如何制作OruxMaps離線地圖
- 校企汽修專業(yè)戰(zhàn)略合作協(xié)議書
評論
0/150
提交評論