freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

畢業(yè)設(shè)計-簡易代理服務(wù)器的設(shè)計—論文(編輯修改稿)

2025-01-06 17:42 本頁面
 

【文章內(nèi)容簡介】 osesocket函數(shù)關(guān)閉套接字,如果沒有錯誤發(fā)生,函數(shù)返回 0,否則返回 SOCKET_ERROR。 指定本地地址- bind() 當(dāng)一個套接字用 socket()創(chuàng)建后,存在一個名字空間 (地址族 ),但它沒有被命名。 bind()將套接字地址(包括本地主機地址和本地端口地址)與所創(chuàng)建的套接字號聯(lián)系起來,即將名字賦予套接字, 以便能夠有效地標(biāo)識套接字。它用在沒有建立連接的套接字上, 如果沒有錯誤發(fā)生, bind()返回 0。否則返回值 SOCKET_ERROR。 當(dāng)然,客戶端程序也可以在不顯示綁定地址和端口號的情況下發(fā)送數(shù)據(jù)或者連接。這時系統(tǒng)會默認(rèn)地為套接字綁定一個本地端口值。注意:地址在建立套接字通 信過程中起著重要作用, 程序使用中通??刻畛鋝ockaddr_in 結(jié)構(gòu)來綁定套接字到本地地址。綁定到套接字上的本地名稱包括主機地址、協(xié)議號和端口號 3部分。 設(shè)置監(jiān)聽狀態(tài) listen() Listen 函數(shù)設(shè)置套接字進入監(jiān)聽狀態(tài)。為了接受連接,首先使用 socket函數(shù)創(chuàng)建套接字,然后使用 bind 函數(shù)將它綁定到本地地址,再用 listen 函數(shù)為到達(dá)的連接指定 backlog,最后使用 accept 函數(shù)接受請求的連接。 Listen 函數(shù) 僅應(yīng)用在支持連接的套接字上,如 SOCK_STREAM 類型。函數(shù)執(zhí)行成功后,套接字 將 進入被 動模式,到來的連接會通知要排隊 并 等候接受處理。在同一時間處理多個連接請求的服務(wù)器通常使用 listen 函數(shù),如果一個連接請求到達(dá)并且排隊也滿,客戶端將接收錯誤。 建立套接字連接- connect()和 accept() 這兩個系統(tǒng)調(diào)用用于完成一個完整相關(guān)的建立, 用于 客戶機與網(wǎng)絡(luò)中的服 第 7 頁 共 20頁 務(wù)器建立連接時,用 connect()這個調(diào)用連接將請求發(fā)到偵聽方。之后,服務(wù)端就會調(diào)用 accept(),而在 調(diào) 用 accept ()的參數(shù)前應(yīng)該先調(diào)用過 listen(),Accept 函數(shù)定義如下: SOCKET accept(SOCKET soc, struct sockaddr * addr, int * addrlen)。 收發(fā)數(shù)據(jù) send()和 recv() 對流套接字來說,一般使用 send 和 recv 函數(shù)來收發(fā)數(shù)據(jù)。 Send 函數(shù)在一個連接的套接字上發(fā)送緩沖區(qū)內(nèi)的數(shù)據(jù),返回發(fā)送數(shù)據(jù)的實際字節(jié)數(shù)。 Recv 函數(shù)從對方接收數(shù)據(jù),并將其存儲到指定的緩沖區(qū)。 Flags 參數(shù)在這兩函數(shù)中通常設(shè)為 0。 3 設(shè)計方案 基本函數(shù)設(shè)計 我們根據(jù)上面討論的代理服務(wù)器內(nèi)容容易畫出代理服務(wù)器的簡單流程模型: 圖 2 代理服務(wù)器的流程 從圖中看出,我們需要設(shè)計的基本 功能函數(shù)為 ClientToProxy 和ProxyToServer。其中, ClientToProxy 用于實現(xiàn) 收取 Client 數(shù)據(jù)請求并 傳給Server。ProxyToServer 用于 接收 Server 的數(shù)據(jù)、傳給請求 Client。在處理數(shù)據(jù)請求的過程中,我們必須知道 Server 的地址,這是非常重要的。這需要設(shè)計一個函數(shù)來解析地址,設(shè)計過程中用 ReceiveInformation 函數(shù)來實現(xiàn)。 另外,任何 Windows Socket函數(shù)對 IP地址和端口號的引用和傳送給 Windows Sockets 函數(shù)的 IP 地址和端 口號均是按照網(wǎng)絡(luò)順序組織的,這也包括了sockaddr_in 結(jié)構(gòu)這一數(shù)據(jù)類型中的 IP 地址域和端口域 (但不包括 sin_family域 )??紤]到一個應(yīng)用程序通常用“時間”服務(wù)對應(yīng)的端口來和服務(wù)器連接,而服務(wù)器提供某種機制來通知用戶使用另一端口,因此 gethostbyname()函數(shù)返回的端口號已經(jīng)是網(wǎng)絡(luò)順序了,可以直接用來組成一個地址,而不需要進行轉(zhuǎn)換。如果用戶輸入一個數(shù),而且指定使用這一端口號,則應(yīng)用程序必須在使用它建立地址以前,把它從主機順序轉(zhuǎn)換網(wǎng)絡(luò)順序(使用 htons()函數(shù))。相應(yīng)地,應(yīng)用C lien t P ro x y Se rv e r數(shù)據(jù)請求 轉(zhuǎn)發(fā)請求返回請求數(shù)據(jù) 回應(yīng)數(shù)據(jù)C lien tT o P ro x yP ro x y T o S e rv e r 第 8 頁 共 20頁 程序希望顯示包 含于某一地址中的端口號,這一端口號就必須在被顯示前從網(wǎng)絡(luò)順序轉(zhuǎn)換到主機順序( ntohs)。 多線程流程 由于 代理服務(wù)器 和大多數(shù)服務(wù)器一樣,如果要處理多個請求,它應(yīng)該使用多線程。其基本規(guī)劃如下: 1. 等待來自客戶( Web 瀏覽器)的請求 2. 啟動一個新的線程,以處理客戶連接請求 3. 讀取瀏覽器請求的第一行(該行內(nèi)容包含了請求的目標(biāo) URL) 4. 分析請求的第一行內(nèi)容,得到目標(biāo)服務(wù)器的 地址 和端口 5. 打開一個通向目標(biāo)服務(wù)器(或下一個代理服務(wù)器,如合適的話)的 Socket 6. 把請求的第一行發(fā)送到輸出 Socket 7. 把請求的剩余部分發(fā)送到輸出 Socket 8. 把目標(biāo) Web 服務(wù)器返回的數(shù)據(jù)發(fā)送給發(fā)出請求的瀏覽器 當(dāng)然,如果考慮細(xì)節(jié)的話,情況會更復(fù)雜一些。實際上,這里主要有兩個問題要考慮:第一,從 Socket 按行讀取數(shù)據(jù)最適合進一步處理,但這會產(chǎn)生性能瓶頸;第二,兩個 Socket 之間的連接必需高效。有幾種方法可以實現(xiàn)這兩個目標(biāo),但每一種方法都有各自的代價。例如,如果要在數(shù)據(jù)進入的時候進行過濾,這些數(shù)據(jù)最好按行讀??;然而,大多數(shù)時候,當(dāng)數(shù)據(jù)到達(dá)代理服務(wù)器時,立即把它轉(zhuǎn)發(fā)出去更適合高效這一要求。另外,數(shù)據(jù)的發(fā)送和接收也可以使用多個獨立的線程,但大量地創(chuàng)建和 拆除線程也會帶來性能問題。因此,對于每一個請求,我們將用一個線程處理數(shù)據(jù)的接收和發(fā)送,同時在數(shù)據(jù)到達(dá)代理服務(wù)器時,盡可能快速地把它轉(zhuǎn)發(fā)出去 。 4 服務(wù)器的實現(xiàn) 環(huán)境創(chuàng)建 設(shè)計使用 Visual C++ 作為編程工具,采用 Windows XP 系統(tǒng)平臺。剛開始時運行 VC++ 開發(fā)工具,單擊菜單“ Tools/Options...” ,彈出 Options對話框,選擇 Directories 選項卡,首先在 “ Show directories for:” 下拉菜單中選擇 Include files,將 SDK 中頭文件的目錄添 加到:“ Directories:”列 表中,如圖 3 所示: 第 9 頁 共 20頁 圖 3 Include files設(shè)置 然后在 “ Show directories for:” 下拉菜單中選擇 Library files,進行同樣的設(shè)置,如圖 4 所示。在 VC主窗口中,執(zhí)行主菜單“ File” /“ New” 命令,建立一個控制臺應(yīng)用程序類型的工程,工程名為“ MiniProxy”;點擊“ OK”后選擇“ an application that supports MFC” ,之后一直確定 ,完成項目工程的創(chuàng)建工作。 圖 4 Library files設(shè)置 功 能實現(xiàn) 數(shù)據(jù)變量定義 定義代表 協(xié)議 的 變量 HTTP, 定義緩 沖區(qū)大小變量MAXBUFFERSIZE。運用結(jié)構(gòu)體 Str_BasalSocket,里面定義客戶端到代理服務(wù)器及代理服務(wù)器到 Server 間套接字兩個,以及客戶端、代理服務(wù)器和 Server 間的連接狀態(tài)變量兩個; Str_ProParam 結(jié)構(gòu)體定義 Server 地址變量,指向結(jié)構(gòu)體 Str_BasalSocket 的指針,聯(lián)結(jié) Server 主機的端口變量和代理服務(wù)器到Server 連接狀態(tài)的句柄變量,這個結(jié)構(gòu)體是用來代理服務(wù)器與 Server 主機交換信息 。 第 10 頁 共 20頁 啟動代理服務(wù)器 這里,在運用套接字編程中由于 Winsock在被調(diào)用時是動態(tài)鏈接庫 Winsock DLL 形式實現(xiàn)的,首先需調(diào)用 WSAStartup()函數(shù)對 Winsock DLL 進行初始化,它的第一個參數(shù)指定要加載的 Winsock 庫的版本,高字節(jié)為次版本號,低字節(jié)為主版本號;第二個參數(shù)是用來返回 DLL 庫的詳細(xì)信息,是指向 WSADATA 結(jié)構(gòu)的指針。實現(xiàn)為: WSADATA wsaData。 if(::WSAStartup(0x202,amp。wsaData)!=0) { printf(\nError in Startup session.\n)。 WSACleanup()。 return 1。 } 之后,創(chuàng)建一個代理服務(wù)器( Proxy)用于網(wǎng)絡(luò)通信的套接字 listen_socket。為了將本地地址附加到所創(chuàng)建的套接字上以便能夠有效地標(biāo)識套接字,我們需用 bind 函數(shù)來完成這一步: SOCKET listen_socket。 sockaddr_in local。 定義用于保存 socket 信息的變量。 =AF_INET。 地址家族用于指定地址格式。 =INADDR_ANY。 此處將 本機 IP 地址填入 此變量。 =htons(port)。 字節(jié)順序轉(zhuǎn)換函數(shù) 用于將 將 u_short類型變量 port從 主機字節(jié)順序轉(zhuǎn)化到TCP/IP 網(wǎng)絡(luò)字節(jié)順序 (即: host to nework short)。 再用 listen_socket=socket(AF_INET,SOCK_STREAM,0)語句 打開 socket 描述符 。 if(::bind(listen_socket,(sockaddr *)amp。local,sizeof(local))!=0) { printf(\n Error in Binding socket.)。 WSACleanup()。 return 3。 } 第 11 頁 共 20頁 綁定完成后,緊接著就將此套接字置入監(jiān)聽以準(zhǔn)備接受客戶端的連接請求,調(diào)用 listen 函數(shù), ::listen(listen_socket,5),最后就可以啟動處理線程進行偵聽。 請求處理過程 在這一步設(shè)計函數(shù) ClientToProxy 來處理收到客戶請求,并將請求合理傳送至 Server(客戶請求的數(shù)據(jù)服務(wù)器 )。 當(dāng)客戶端有請求發(fā)到代理服務(wù)器時,偵聽 中的 Proxy 就會調(diào)用函數(shù) accept來響應(yīng)對主機的連接請求,同時 Proxy 會啟動另一個偵聽線程,以準(zhǔn)備接收客戶端的下一個請求。 msg_socket=accept(listen_socket,(struct sockaddr*)amp。from,amp。fromlen)。 此處 接收客戶端的連接請求 ,返回客戶端的地址和端口。 AfxBeginThread(ClientToProxy,pParam)。 啟動另一偵聽 ,用來處理客戶端傳來的另一個請求。 如果此客戶端到代理服務(wù)器的連接正確,我們就在這一 socket 連接上使用revc 函數(shù)接收數(shù)據(jù)。 =FALSE。 =TRUE。 =msg_socket。 retval=recv(,Buffer,sizeof(Buffer),0)。 如果從套接字接收數(shù)據(jù)失敗,用下面代碼給出提示,同時關(guān)閉 socket 句柄,設(shè)置客戶端到服務(wù)器的狀態(tài)為關(guān)閉。 if(retval==SOCKET_ERROR) { printf(\nError Receive)。 if(==FALSE) { closesocket()。 =TRUE。 } } 當(dāng)客戶端關(guān)閉連接時,這時接收的數(shù)據(jù)為 0,也需要將此時 socket 狀態(tài)進行調(diào)整: printf(Client Close connection\n)。 closesocket()。 =TRUE。 第 12 頁 共 20頁 下面的一步,需要把這些數(shù)據(jù)信息傳給 Server。為此,需要解析出 Server的地址, 創(chuàng)建函 數(shù) ReceiveInformation 來 實現(xiàn)此 功能, 即聲明 int ReceiveInformation( char * str, char *address, int * port),其中將實現(xiàn): char buf[MAXBUFFERSIZE], mand[512], proto[128]。 由于客戶端在連接時,都會和代理服務(wù)器連接,發(fā)出請求,一般為 mand url(//GET == GET / )形式 ,定義buf用于存儲接收到的請求字符串 。mand用于保存 get,con,user等命令,這里顯然是 get。proto 保存協(xié)議。 p=strstr(buf,HTTP)。 這里 strstr 調(diào)用用于在 字符串 buf 中尋找 第一次出現(xiàn)的位置( 它 不會 比較結(jié)束符 NULL),將值賦給指針 p。如果分析出請求是 HTTP 協(xié)議類型的,將進行如下處理,首先將字符串協(xié)議部份去掉,把地址存于 address 參數(shù)中,端口設(shè) 為缺省的 80,最終返回這些信息,成功解析出 Server 端的地址信息。 至此,啟動一個新的子線程,用于處理代理服務(wù)器和數(shù)據(jù)服務(wù)器間的數(shù)據(jù)傳輸。這個功能將在下面實現(xiàn)。 在剛才的處理線程中,如果代理服務(wù)器、 Server 以及客戶端、代理服務(wù)器端的連接沒有關(guān)閉,就使用 send 命令發(fā)送請求數(shù)據(jù)給數(shù)據(jù)服務(wù)器( Server),成功時返回接收的字節(jié)數(shù),錯誤時顯示出錯信息,并關(guān)閉代理服
點擊復(fù)制文檔內(nèi)容
公司管理相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖片鄂ICP備17016276號-1