




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
38/38信息通信網絡概論實驗指導書
目錄實驗一TCP/IP協議與Socket編程認識實驗 4一、 實驗目的 4二、 實驗內容 4三、 實驗原理 4四、 實驗步驟 5五、 思考題或討論題 6實驗二FTP客戶端通信程序設計 7一、 實驗目的 7二、 實驗內容 7三、 實驗原理 7四、 思考題或討論題 9實驗三基于客戶/服務器模式的網絡通信編程實現 11一、 實驗目的 11二、 實驗內容 11三、 實驗原理 11四、 應用程序的設計方法和步驟 12五、 聊天室應用程序設計的具體說明 141、聊天室的工作流程 142、套接字事件處理 153、系統實現 163.1利用MFCAppWizard生成程序框架 163.2增加控件對象 163.3從CAsyncSocket類繼承 163.4建立客戶機與服務器之間的連接 163.5發送和接收數據 173.6終止連接 174、結束語 17六、 思考題或討論題 18實驗四﹑計算機網絡通信應用程序設計 19(一)基于TCP/IP的計算機網絡通信應用程序設計 19一、 實驗目的 19二、 實驗內容 19三、 實驗步驟 19(二)基于UDP/IP的計算機網絡通信應用程序設計 20一、 實驗目的 20二、 實驗內容 20三、 實驗步驟 21四、 思考題或討論題 21附錄:實驗中需要用到的WINSOCKAPI函數和數據結構 22accept(): 22bind() 23closesocket(): 24connect(): 26listen(): 27socket(): 28recv(): 29send(): 31WSAAsyncSelect(): 32WSAStartup(): 36Gethostbyname 37Gethostbyaddr 38inet_ntoa 38inet_addr 38WSADATA和LPWSADATA 38
實驗一TCP/IP協議與Socket編程認識實驗實驗目的熟悉TCP/IP協議的功能和網絡操作;了解基于SOCKET的編程原理;編寫一個小型的Socket實用程序,初步了解Windows環境下使用Socket的編程。實驗內容在已有的程序框架下,編寫一個查詢主機地址和域名的程序。實現功能:輸入域名查詢IP地址;輸入IP地址查詢域名。實驗原理什么是WindowsSockets規范?WindowsSockets規范以U.C.Berkeley大學BSDUNIX中流行的Socket接口為范例定義了一套MicosoftWindows下網絡編程接口。它不僅包含了人們所熟悉的BerkeleySocket風格的庫函數;也包含了一組針對Windows的擴展庫函數,以使程序員能充分地利用Windows消息驅動機制進行編程。WindowsSockets規范本意在于提供給應用程序開發者一套簡單的API,并讓各家網絡軟件供應商共同遵守。此外,在一個特定版本Windows的基礎上,WindowsSockets也定義了一個二進制接口(ABI),以此來保證應用WindowsSocketsAPI的應用程序能夠在任何網絡軟件供應商的符合WindowsSockets協議的實現上工作。因此這份規范定義了應用程序開發者能夠使用,并且網絡軟件供應商能夠實現的一套庫函數調用和相關語義。遵守這套WindowsSockets規范的網絡軟件,我們稱之為WindowsSockets兼容的,而WindowsSockets兼容實現的提供者,我們稱之為WindowsSockets提供者。一個網絡軟件供應商必須百分之百地實現WindowsSockets規范才能做到現WindowsSockets兼容。任何能夠與WindowsSockets兼容實現協同工作的應用程序就被認為是具有WindowsSockets接口。我們稱這種應用程序為WindowsSockets應用程序。WindowsSockets規范定義并記錄了如何使用API與Internet協議族(IPS,通常我們指的是TCP/IP)連接,尤其要指出的是所有的WindowsSockets實現都支持流套接口和數據報套接口.應用程序調用WindowsSockets的API實現相互之間的通訊。WindowsSockets又利用下層的網絡通訊協議功能和操作系統調用實現實際的通訊工作。它們之間的關系如圖1-1。Winsock編程模型建立socket。程序使用socket進行網絡時,必須先建立一個socket。為了建立一個socket,成需要調用socket函數。例子:socket_handle=socket(protocol_family,_socket_type,protocol);配置一個socket。為了配置一個,程序可使用WinsockAPI中不同的函數。一般來講,每個socket需要五種信息:本地和遠地機的IP地址,本地和遠地進程的協議端口,聯接上使用的協議。連接一個socket。面向連接客戶程序必須提供給Socket的唯一地址信息是遠地主機信息—IP地址和協議端口。使用一個Socket,程序能夠使用WinsockAPI在一個配置好的Socket上傳送和接收數據。I/O函數如下:Send,通過連接的Socket傳送數據,使用特殊的標志控制Socket的行為。Sendto,將數據傳送給Socket地址結構指定的主機,傳送時使用一個簡單的報文緩沖區。Recvfrom,從Socket接收數據,選擇發送主機的網絡地址,傳送時使用一個簡單的報文緩沖區。使用一個連接的Socket。由于Send函數不能指定目的地址,因此,程序只能在連接的Socket上使用它。也就是說,在程序使用Send函數之前,必須建立一個Socket。使用一個無連接的Socket。當沒有建立Socket連接時,上述的Send函數便不能使用,這是需要用Sendto函數。實驗步驟網絡程序初始化,服務器和客戶端WinSockAPI均要求在調用其他WinSock函數以前先調用WSAStartUp函數初始化。創建套接字Socket()。配置并啟動套接字。通過Socket發送和接收數據。程序結束時必須關閉Socket,使用與WSAStartUp()相對應的函數WSACleanUp(),釋放所分配的內部緩沖區和其他資源。思考題或討論題1.WinInet有什么作用?2.結合本次實驗,談談使用MFCWinInet類有哪些優點?
實驗二FTP客戶端通信程序設計實驗目的了解Windows下的TCP/IP通信方式與網絡操作熟悉FTP的編程的過程;學會用可視化編程語言編寫調試簡單的通信程序。實驗內容在已有的程序框架下,編寫一個FTP客戶端程序。實現功能:連接到FTP主機,下載FTP文件服務器文件列表;切換訪問目錄;向FTP服務器發送文件(上傳文件);從FTP服務器下載文件(下載文件)。實驗原理在使用MFC編程時,要連接到FTP服務器是一件非常簡單的事情,只需要兩個簡單的步驟,首先必須建立一個CinternetSession對象,用類CinternetSession創建并初始化一個或幾個同時存在的Internet會話(Session),并描述與代理服務器的連接(如果有必要的話),如果在程序運行期間需要保持與Internet的廉潔,可以創建一個CinternetSession對象作為類CwinApp的成員。MFC中的類C管理我們與Internet服務器的連接,并直接操作服務器上的目錄和文件,的WinInet支持的三個Internet功能之一,我們需要先創建一個CinternetSession實例和一個C對象就可以實現和一個FTP服務器通信,我們不需要直接創建C對象,而是通過調用CinternetSession::Get來完成這項工作。他創建C對象并返回一個指向該對象的指針。在FTP連接的程序中,主要適用下列7個函數:CInternetSession對象語法:CInternetSession(LPCTSTRpstrAgent,DWORDdwConText,DWORDdwAccessType,LPCTSTRpstrProxyName,LPCTSTRpstrProxyBypass,DWORDdwFlags);注釋:在創建CInternetSession對象時調用這個成員函數,CInternetSession是應用程序第一個要調用的Internet函數,它將創始化內部數據結構,以備將來在應用程序中調用。如果dwFlags包含INTERNET_FLAG_ASYNC,那末從這個句柄派生的所有的句柄,在狀態回調例程注冊之前,都會出現異步狀態。如果沒有打開Internet連接,CInternetSession就會拋出一個例外,fxThorowInternetException。Get()函數。語法:C*CIternetSession::Get(LPCTSTRpstrServer,LPCTSTRpstrUserName,LPCTSTRpstrPassword,INTERNET_PORTnPort,BOOLbPassive);注釋:調用這個函數建立一個FTP連接,并獲得一個指向C對象的指針,Get連接到一個FTP服務器,創建并返回指向C對象的指針,它不在服務器上進行任何操作。如果打算讀寫文件,必須進行分步操作。關于查找,打開和讀/寫文件的信息需參考C和C類。對這個函數的調用返回一個指向C對象的指針。如果調用失敗,檢查拋出的CInternetException對象,就可以確定失敗的原因。GetFile()函數。語法:BOOLGetpstrRemotepstrLocalbFailExists,DWORDdwAttributes,DWORDdwFlags,DWORDdwContext);注釋:調用這個成員函數,可以從FTP服務器取得文件,并且把文件保存在本地機器上。GetFile()函數是一個比較高級的例程,它可以處理所有有關從FTP服務器讀文件,以及把文件存放在本地機器上的工作。如果dwFlags為,文件數據的傳輸也會把控制和格式符轉化為Windows中的等階符號。默認的傳輸模式是二進制模式,文件會以和服務器上相同的格式被下載。pstrRemoteFile和pstrLocalFile可以是相對于當前目錄的部分文件名,也可以是全文件名,在這兩個名字中間,都既可以用反斜杠(\)或者正斜杠(/)來作為文件名的目錄分隔符,GetFile()在使用前會把目錄分隔符轉化為適當的字符。可以用自己選擇的值來取代dwContext默認的值,設置為上下文標識符與C對象的定位操作有關,這個操作由C中的CInternetSession對象創建。返回給CInternetSession::OnStatusCallBack的值指出了所標識操作的狀態。如果調用成功,函數的返回為非0,否則返回0,如果調用失敗,可以調用Win32函數GetLastError(),確認出錯的原因。PutFile()函數。語法:BOOLPutpstrLocalFile,LPCTSTRpstrRemovedwFlags,DWORDdwContext);注釋:調用這個成員函數可以把文件保存到FTP服務器。PutFile()函數是一個比較高級的例程,它可以處理有關把文件存放到服務器上的工作。只發送數據,或要嚴格控制文件傳輸的應用程序,應該調用OpenFile和CInternet::Write。利用自己選擇的值來取代dwContext默認的值,設置為上下文標識符,上下文標識符是CInternetSession對象創建的C對象的特定操作有關,這個值返回給CInternetSession::OnStateCallBack,從而把操作的狀態通報給它所標識的上下文。如果調用成功,函數的返回為非0,否則返回0,如果調用失敗,可以調用Win32函數GetLastError(),確認出錯的原因。FTP文件查找函數。調用這個成員函數構造一個C對象。FindFile()函數。調用這個函數查找FTP文件,調用它檢索到第一個FTP文件后,可以調用FindNextFile()檢索后面的FTP文件。FindNextFile()函數。調用這個函數繼續查找文件,在調用任何屬性以前,必須已經至少調用過一次此函數。以上函數的具體使用方法可以參見MSDN。思考題或討論題1.WinInet有什么作用?2.結合本次實驗,談談使用MFCWinInet類有哪些優點?
實驗三基于客戶/服務器模式的網絡通信編程實現(基于Socket的網絡聊天室的設計與實現)實驗目的進一步了解網絡編程的過程;掌握Windows環境下基于WinSock的編程方法和通信實現;熟悉客戶/服務器模式的網絡通信編程實現,編寫一個聊天工具,即以客戶端和服務器端的模式進行互發消息。實驗內容Internet上可以提供一種叫IRC的服務。使用者通過客戶端的程序登錄到IRC服務器上,就可以與登錄在同一IRC服務器上的客戶進行交談,這也就是平常所說的聊天室。在已有的程序框架下,編寫一個類似的聊天程序。實現功能:服務器端:建立Socket,綁定端口,并監聽;接受客戶端的連接;與客戶端進行通訊;斷開連接。客戶端:建立Socket,并申請連接到服務器;與服務器進行通訊;斷開連接。實驗原理一個在建立分布式應用時最常用的范例便是客戶機/服務器模型。在這種方案中客戶應用程序向服務器程序請求服務。這種方式隱含了在建立客戶機/服務器間通訊時的非對稱性。客戶機/服務器模型工作時要求有一套為客戶機和服務器所共識的慣例來保證服務能夠被提供(或被接受)。這一套慣例包含了一套協議。它必須在通訊的兩頭都被實現。根據不同的實際情況,協議可能是對稱的或是非對稱的。在對稱的協議中,每一方都有可能扮演主從角色;在非對稱協議中,一方被不可改變地認為是主機,而另一方則是從機。一個對稱協議的例子是Internet中用于終端仿真的TELNET。而非對稱協議的例子是Internet中的FTP。無論具體的協議是對稱的或是非對稱的,當服務被提供時必然存在“客戶進程”和“服務進程”。一個服務程序通常在一個眾所周知的地址監聽對服務的請求,也就是說,服務進程一直處于休眠狀態,直到一個客戶對這個服務的地址提出了連接請求。在這個時刻,服務程序被“驚醒”并且為客戶提供服務-對客戶的請求作出適當的反應。這一請求/相應的過程可以簡單的用圖2-1表示。雖然基于連接的服務是設計客戶機/服務器應用程序時的標準,但有些服務也是可以通過數據報套接口提供的。應用程序的設計方法和步驟服務端建立Socket初始化WinSock的動態連接庫后,需要在服務器端建立一個監聽的Socket,為此可以調用Socket()函數用來建立這個監聽的Socket,并定義此Socket所使用的通信協議。此函數調用成功返回Socket對象,失敗則返回INVALID_SOCKET(調用WSAGetLastError()可得知原因,所有WinSocket的函數都可以使用這個函數來獲取失敗的原因)。綁定端口接下來要為服務器端定義的這個監聽的Socket指定一個地址及端口(Port),這樣客戶端才知道待會要連接哪一個地址的哪個端口,為此我們要調用bind()函數,該函數調用成功返回0,否則返回SOCKET_ERROR。監聽當服務器端的Socket對象綁定完成之后,服務器端必須建立一個監聽的隊列來接收客戶端的連接請求。listen()函數使服務器端的Socket進入監聽狀態,并設定可以建立的最大連接數(目前最大值限制為5,最小值為1)。該函數調用成功返回0,否則返回SOCKET_ERROR。服務器端的Socket調用完listen()后,如果此時客戶端調用connect()函數提出連接申請的話,Server端必須再調用accept()函數,這樣服務器端和客戶端才算正式完成通信程序的連接動作。為了知道什么時候客戶端提出連接要求,從而服務器端的Socket在恰當的時候調用accept()函數完成連接的建立,我們就要使用WSAAsyncSelect()函數,讓系統主動來通知我們有客戶端提出連接請求了。該函數調用成功返回0,否則返回SOCKET_ERROR。服務器端接受客戶端的連接請求當Client提出連接請求時,Server端hwnd視窗會收到WinsockStack送來我們自定義的一個消息,這時,我們可以分析lParam,然后調用相關的函數來處理此事件。為了使服務器端接受客戶端的連接請求,就要使用accept()函數,該函數新建一Socket與客戶端的Socket相通,原先監聽之Socket繼續進入監聽狀態,等待他人的連接要求。該函數調用成功返回一個新產生的Socket對象,否則返回INVALID_SOCKET。結束socket連接結束服務器和客戶端的通信連接是很簡單的,這一過程可以由服務器或客戶機的任一端啟動,只要調用closesocket()就可以了,而要關閉Server端監聽狀態的socket,同樣也是利用此函數。客戶端客戶端比較簡單,只有一個socket,與服務端進行連接。連接建立好后,通過此SOCKET發送和接收信息。建立客戶端的Socket客戶端應用程序首先也是調用WSAStartup()函數來與Winsock的動態連接庫建立關系,然后同樣調用socket()來建立一個TCP或UDPsocket(相同協定的sockets才能相通,TCP對TCP,UDP對UDP)。與服務器端的socket不同的是,客戶端的socket可以調用bind()函數,由自己來指定IP地址及port號碼;但是也可以不調用bind(),而由Winsock來自動設定IP地址及port號碼。提出連接申請客戶端的Socket使用connect()函數來提出與服務器端的Socket建立連接的申請,函數調用成功返回0,否則返回SOCKET_ERROR。數據的傳送雖然基于TCP/IP連接協議(流套接字)的服務是設計客戶機/服務器應用程序時的主流標準,但有些服務也是可以通過無連接協議(數據報套接字)提供的。介紹一下TCPsocket與UDPsocket在傳送數據時的特性:Stream(TCP)Socket提供雙向、可靠、有次序、不重復的資料傳送。Datagram(UDP)Socket雖然提供雙向的通信,但沒有可靠、有次序、不重復的保證,所以UDP傳送數據可能會收到無次序、重復的資料,甚至資料在傳輸過程中出現遺漏。由于UDPSocket在傳送資料時,并不保證資料能完整地送達對方,所以絕大多數應用程序都是采用TCP處理Socket,以保證資料的正確性。一般情況下TCPSocket的數據發送和接收是調用send()及recv()這兩個函數來達成,而UDPSocket則是用sendto()及recvfrom()這兩個函數,這兩個函數調用成功發揮發送或接收的資料的長度,否則返回SOCKET_ERROR。聊天室應用程序設計的具體說明1、聊天室的工作流程Socket()Socket()Bind()Listen()服務器偵聽套接字Connect()Accept()Closesocket()Send()Recv()創建連接套接字客戶機連接套接字Socket()Bind()Recv()Send()Closesocket()Closesocket()首先,服務器要創建一個用于偵聽的套接字,為該套接字分配地址之后,調用listen()函數使它處于偵聽狀態;客戶機在創建套接字完畢后,為套接字分配地址,然后調用connect()函數,請求與服務器套接字連接;服務器套接字在收到客戶機的連接請示后,調用accept()函數,該函數創建一個用于連接的套接字。應用該套接字和客戶機上的連接套接字,用戶就可以在服務器和客戶機之間進行數據傳輸了。在結束傳輸之后,客戶機調用closesocket()函數關閉套接字,服務器也調用該函數關閉用于偵聽和連接的套接字。2、套接字事件處理消息處理函數,這些函數并不對套接字作實質上的操作,是Windows為套接字加上消息驅動的產物。它們和特定的套接字消息相關聯,當消息到來時,應用程序框架就調用這些函數。它們都是CAsyncSocket類的虛函數,因為MFC庫中沒有定義這些函數的內容,程序員必須根據需要重載這些函數,把對套接字進行實質操作的函數加進這些函數中。OnAccept():監聽套接字在斷口聽到連接請求時,應用程序框架調用該函數以告之可以接受或拒絕連接請求,調用Accept來接受請求,建立連接。OnConnect():當客戶端套接字連接請求完成后,應用程序框架調用該函數,告之是否成功。OnSend():框架調用該函數通知該套接字現在可以調用Send函數開始傳送數據。OnReceive():框架調用該函數通知套接字可以調用Receive函數從數據緩沖區中取數據。OnClose():框架調用該函數告之與其相連的對方套接字已被關閉。3、系統實現3.1利用MFCAppWizard生成程序框架在VisualC++的IDE環境下選擇菜單File—New—Projects—MFCAppWizard(exe)—ProjectName—“OK”—“NEXT”—WindowsSockets—“Finish”按鈕,選擇“OK”按鈕,應用程序的框架就將自動創建。3.2增加控件對象在創建了應用程序框架之后,可以布置程序的主對話框,向應用程序的主對話框添加控件。設計好了對話框之后,選取View菜單中的ClassWizard菜單項,或直接按“Ctrl+W”,打開MFCClassWizard,將對話框中的控件和變量相關聯,其關系如下表所示。變量說明表對象名稱類別類別IDC_BTN_CONNECTm_btnConnectControlCButtonIDC_COMBO_TYPEm_cmbTypeControlCComboBoxIDC_EDIT_MSGm_strMsgValueCStringIDC_EDIT_SERVNAMEm_strServNameValueCStringIDC_EDIT_SERVPORTm_nSerPortValueIntIDC_LIST_RECEIVEDm_listReceivedControlCListBoxIDC_LIST_SENTm_listSentControlCListBox3.3從CAsyncSocket類繼承選擇Insert菜單中的NewClass——選取Classtype為GenericClass——在Baseclass的DerivedFrom列中輸入CAsyncSocket,——在As列中接受默認值public,點擊”OK”按鈕,就可以把這個新創建的類添加到應用程序中。向該套接字類中添加一個成員變量,用作指向父對話框窗口的指針,指針變量的類型為CTalkDlg*(Cdialog的派生類),變量名為m_pDlg,訪問權限為私有。最后,添加套接字類事件處理函數,這些函數將用于調用對話框中名稱類似的那些函數。3.4建立客戶機與服務器之間的連接為了完成連接,需要添加對套接字事件的處理函數,在對話框類中添加OnAccept()事件處理函數和OnConnect()事件處理函數。如果現在可以編譯和運行應用程序,就可以啟動兩個副本,把其中一個設置為偵聽模式,然后把另一個應用程序與之相連接。為此,先向對話框類()添加三個成員函數,這三個函數是套接字類()的事件處理函數需要調用的。把三個函數的類型都指定為void,訪問權限為公共。指定第一個函數聲明為OnSend(),第二個函數的聲明為OnReceive,第三函數的聲明為OnClose。3.5發送和接收數據如果兩個應用程序間建立了連接,用戶就能夠在對話框窗口中的編輯框中輸入文本消息,然后單擊“發送”按鈕,就應該可以把消息發送到另一個應用程序,一旦消息發送出去了,它將被添加到已發送消息的列表框中。當“發送”按鈕被單擊之后,應用程序需要檢查是否有消息輸入了編輯框,獲取該消息的長度,并發送該消息,然后把此消息添加到列表框中。為了在應用程序中添加此項功能,使用ClassWizard向“發送”按鈕(ID:IDOK)的單擊事件(BN—CLICKED)添加一個事件處理函數,注意不要接受默認的函數名,將函數名改成OnSendMsg(),編輯該函數。對于消息的接收方,當套接字的OnReceive事件被觸發時,表明一個消息已經到達了,可以用Receive()函數從套接字檢索到該消息。如果消息被順利檢索到,需要把接收的字符數組轉換成Cstring類型,并把接收的消息添加到已接收的消息的列表框中。通過編輯對話框類(CtalkDlg)的OnReceive()函數。3.6終止連接結束消息傳送之后應該終止兩個應用程序之間的連接,這個終止連接的操作是由客戶機應用程序的用戶通過單擊“斷開”按鈕來實現的。然后應用程序會接收到一個OnClose套接字事件。和建立連接的過程相反,連接的套接字需要斷開,發送消息的控件需要置為禁用狀態。在客戶端,“連接”按鈕控件由禁用狀態變成可用,因為應用程序允許客戶機程序改變某些參數,并打開與另一個服務器程序的連接。同時,服務器應用程序繼續偵聽是否有其他的連接請求,偵聽的端口等信息不變。4、結束語這個應用程序在MFCWinSock編程中很有代表性,可以用于兩臺計算機之間進行字符串傳輸;創建思路簡單,就是利用MFCAppWizard生成程序框架,通過對CAsynSocket類增加一個指向對話框類得指針,對CAsynSocket類中的一些事件處理函數進行重載,使這些套接字事件發生時,應用程序能夠自動到對話框類中尋找合適的函數執行。這個聊天室應用程序是基于客戶/服務器模型的,一個服務器只能支持一個客戶,因此它實際上是一個基于“點對點”模型的應用程序。通過這個應用程序,用戶可以在兩臺計算機之間進行字符串傳輸——即可以為兩個人進行網上聊天提供服務,而且兩個人的傳輸的字符串被保留在程序的列表框中,并且進行分類,分為傳送和接收的字符串。思考題或討論題1.本次實驗所涉及的“實體”是什么?實體間通過什么方式建立協議?2.服務和協議的區別與聯系?本次實驗的協議過程(即客戶-服務器方式)是怎樣建立的?有哪些服務?3、本次實驗的協議提供了什么服務?試想,用此協議還可以提供怎樣的服務?這種服務在自動化學科領域的意義是什么?實驗四﹑計算機網絡通信應用程序設計(一)基于TCP/IP的計算機網絡通信應用程序設計實驗目的1.通過本實驗課程的學習,使學生能夠理解TCP協議通信的基本原理。2.通過運用WinSock接口編寫網絡通信應用程序,掌握TCP網絡應用程序架構的設計思想。3.學會設計利用TCP簡單的應用層協議。實驗內容在Windows網絡環境下,以其中的2臺計算機為對象,構成主從計算機應用系統,設計簡單的應用層協議,開發基于TCP/IP的網絡通信程序,實現數據傳送等。基于TCP的計算機網絡通信程序,實現了兩人點對點聊天的功能,同時,還添加了一定的網絡應用層自定義協議,例如:在聊天過程中輸入/n會在聊天對話框內畫一個牛;輸入/p會在聊天對話框內畫一個電話;在聊天過程中輸入/r會打開一個windows資源管理器,并打開指定的路徑;輸入/l會彈出一個對話框……;(實現以上功能的函數是DoAction,用的到的頭文件是有textprotcol.h)實驗步驟服務器端1:創建套接字并將套接字綁定到一個本地地址和端口上(create)。2:將套接字設為監聽模式,準備接受客戶請求(listen)。3:等待客戶請求到來;請求到來后,接受請求,返回一個新的對應于此次連接的套接字(accept)。4:用返回的套接字和客戶端進行通信(send/receive)。5:返回,等待另一客戶請求。6:關閉套接字。客戶端1:創建套接字(create)。2:向服務器發出連接請求(connect)。3:和服務器進行通信(send/receive)。4:關閉套接字。(二)基于UDP/IP的計算機網絡通信應用程序設計實驗目的1.通過本實驗課程的學習,使學生能夠理解UDP協議通信的基本原理。2.通過運用WinSock接口編寫網絡通信應用程序,掌握UDP網絡應用程序架構的設計思想。3.學會設計利用UDP簡單的應用層協議。實驗內容在Windows網絡環境下,以其中的2臺計算機為對象,構成主從計算機應用系統,設計簡單的應用層協議,開發基于UDP/IP的網絡通信程序,實現數據傳送等。基于UDP的計算機網絡通信程序,實現了多人的點對點聊天功能,同時,還添加了一定的網絡應用層自定義協議,例如:在聊天過程中輸入/n會在聊天對話框內畫一個牛;輸入/p會在聊天對話框內畫一個電話;在聊天中輸入/z會在聊天對話框內畫一個豬的圖案;在聊天過程中輸入/r會打開一個windows資源管理器,并打開指定的路徑……(實現以上功能的函數是DoAction,用的到的頭文件是有textprotcol.h)本程序中的傳輸層協議使用的是UDP/IP協議,建立連接的過程和前面實驗類似。但是,UDP協議的在建立連接中不需要先監聽(listen)網絡,建立連接(connect,accept)等過程,只需要綁定指定的端口。(具體通信過程請參看PPT講義)另外,在該程序實現的過程中使用了多線程。實驗步驟服務器端1.創建套接字并將套接字綁定到一個本地地址和端口上(create)。2.等待接收數據(ReceiveFrom)。3.關閉套接字。客戶端1.創建套接字(create)。2.向服務器發送數據(sendto)。3.關閉套接字。思考題或討論題1、結合所學知識與實驗中的感受,說明TCP協議和UDP協議各自的優缺點。在工業控制的現場中,要通過網絡控制一臺焊接機器人的運行,要求控制數據能正確傳輸。試分析說明,采用哪種運輸層協議比較好?另外,網絡中使用的IP電話服務采用的是哪種運輸層協議?為什么要采用這種協議?并說明理由。2、思考和調研目前常用的通信工具之一:QQ的基本實現方式。考慮其各種不同的應用可能采取的是TCP和UDP中的哪種協議。如果需要對本實驗結果進行進一步改進,有哪些想法。
附錄:實驗中需要用到的WINSOCKAPI函數和數據結構需要包含頭文件#include<winsock.h>accept():在一個套接口接受一個連接。語法:SOCKETPASCALFARaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen);參數:s:套接口描述字,該套接口在listen()后監聽連接。addr:(可選)指針,指向一緩沖區,其中接收為通訊層所知的連接實體的地址。Addr參數的實際格式由套接口創建時所產生的地址族確定。addrlen:(可選)指針,指向存有addr地址長度的整形數。注釋:本函數從s的等待連接隊列中抽取第一個連接,創建一個與s同類的新的套接口并返回句柄。如果隊列中無等待連接,且套接口為非阻塞方式,則accept()阻塞調用進程直至新的連接出現。如果套接口為非阻塞方式且隊列中等待連接,則accept()返回一錯誤代碼。已接受連接的套接口不能用于接受新的連接,原套接口仍保持開放。addr參數為一個返回參數,其中填寫的是為通訊層所知的連接實體地址。addr參數的實際格式由通訊時產生的地址族確定。addrlen參數也是一個返回參數,在調用時初始化為addr所指的地址空間;在調用結束時它包含了實際返回的地址的長度(用字節數表示)。該函數與SOCK_STREAM類型的面向連接的套接口一起使用。如果addr與addrlen中有一個為零NULL,將不返回所接受的套接口遠程地址的任何信息。返回值:如果沒有錯誤產生,則accept()返回一個描述所接受包的SOCKET類型的值。否則的話,返回INVALID_SOCKET錯誤,應用程序可通過調用WSAGetLastError()來獲得特定的錯誤代碼。addrlen所指的整形數初始時包含addr所指地址空間的大小,在返回時它包含實際返回地址的字節長度。錯誤代碼:WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。WSAEFAULT:addrlen參數太小(小于socket結構的大小)。WSAEINTR:通過一個WSACancelBlockingCall()來取消一個(阻塞的)調用。WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。WSAEINVAL:在accept()前未激活listen()。WSAEMFILE:調用accept()時隊列為空,無可用的描述字。WSAENOBUFS:無可用緩沖區空間。WSAENOTSOCK:描述字不是一個套接口。WSAEOPNOTSUPP:該套接口類型不支持面向連接服務。WSAEWOULDBLOCK:該套接口為非阻塞方式且無連接可供接受。bind()將一本地地址與一套接口捆綁。語法:intPASCALFARbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);參數:s:標識一未捆綁套接口的描述字。name:賦予套接口的地址。sockaddr結構定義如下:structsockaddr{u_shortsa_family;charsa_data[14];};namelen:name名字的長度。注釋:本函數適用于未連接的數據報或流類套接口,在connect()或listen()調用前使用。當用socket()創建套接口后,它便存在于一個名字空間(地址族)中,但并未賦名。bind()函數通過給一個未命名套接口分配一個本地名字來為套接口建立本地捆綁(主機地址/斷口號)。在Internet地址族中,一個名字包括幾個組成部分,對于SOCK_PGRAM和SOCK_STREAM類套接口,名字由三部分組成:主機地址,協議號(顯式設置為UDP和TCP)和用以區分應用的端口號。如果一個應用并不關心分配給它的地址,則可將Internet地址設置為INADDR_ANY,或將端口號置為0。如果Internet地址段為INADDR_ANY,則可使用任意網絡接口;在有多種主機環境下可簡化編程。如果端口號置為0,則WINDOWS套接口實現將給應用程序分配一個值在1024到5000之間的唯一的端口。應用程序可在bind()后用getsockname()來獲知所分配的地址,但必需注意的是,getsockname()只有在套接口連接成功后才會填寫Internet地址,這是由于在多種主機環境下若干種Internet地址都是有效的。返回值:如無錯誤發生,則bind()返回0。否則的話,將返回SOCKET_ERROR,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。錯誤代碼:WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。WSAEADDRINUSE:所定端口已在使用中(參見setoption()中的SO_REUSEADDR選項)。WSAEFAULT:namelen參數太小(小于sockaddr結構的大小)。WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。WSAEAFNOSUPPORT:本協議不支持所指定的地址族。WSAEINVAL:該套接口已與一個地址捆綁。WSAENOBUFS:無足夠可用緩沖區,連接過多。WSAENOTSOCK:描述字不是一個套接口。closesocket():關閉一個套接口。語法:intPASCALFARclosesocket(SOCKETs);參數:s:一個套接口的描述字。注釋:本函數關閉一個套接口。更確切地說,它釋放套接口描述字s,以后對s的訪問均以WSAENOTSOCK錯誤返回。若本次為對套接口的最后一次訪問,則相應的名字信息及數據隊列都將被釋放。closesocket()的語義受SO_LINGER與SO_DONTLINGER選項影響,對比如下:選項間隔關閉方式等待關閉與否SO_DONTLINGER不關心優雅否SO_LINGER零強制否SO_LINGER非零優雅是若設置了SO_LINGER,并設置了零超時間隔,則closesocket()不被阻塞立即執行,不論是否有排隊數據未發送或未被確認。這種關閉方式稱為“強制”或“失效”關閉,因為套接口的虛電路立即被復位,且丟失了未發送的數據。在遠端的recv()調用將以WSAECONNRESET出錯。若設置了SO_LINGER并確定了非零的超時間隔,則closesocket()調用阻塞進程,直到所剩數據發送完畢或超時。這種關閉稱為“優雅的”關閉。請注意如果套接口置為非阻塞且SO_LINGER設為非零超時,則closesocket()調用將以WSAEWOULDBLOCK錯誤返回。若在一個流類套接口上設置了SO_DONTLINGER,則closesocket()調用立即返回。但是,如果可能,排隊的數據將在套接口關閉前發送。請注意,在這種情況下WINDOWS套接口實現將在一段不確定的時間內保留套接口以及其他資源,這對于想用所以套接口的應用程序來說有一定影響。返回值:如無錯誤發生,則closesocket()返回0。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。錯誤代碼:WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。WSAENOTSOCK:描述字不是一個套接口。WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。WSAEINTR:通過一個WSACancelBlockingCall()來取消一個(阻塞的)調用。WSAEWOULDBLOCK:該套接口設置為非阻塞方式且SO_LINGER設置為非零超時間隔。connect():建立與一個端的連接。語法:intPASCALFARconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);參數:s:標識一個未連接套接口的描述字。name:欲進行連接的端口名。namelen:名字長度。注釋:本函數用于創建與指定外部端口的連接。s參數指定一個未連接的數據報或流類套接口。如套接口未被捆綁,則系統賦給本地關聯一個唯一的值,且設置套接口為已捆綁。請注意若名字結構中的地址域為全零的話,則connect()將返回WSAEADDRNOTAVAIL錯誤。對于流類套接口(SOCK_STREAM類型),利用名字來與一個遠程主機建立連接,一旦套接口調用成功返回,它就能收發數據了。對于數據報類套接口(SOCK_DGRAM類型),則設置成一個缺省的目的地址,并用它來進行后續的send()與recv()調用。返回值:若無錯誤發生,則connect()返回0。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。對阻塞套接口而言,若返回值為SOCKET_ERROR則應用程序調用WSAGetLsatError()。如果它指出錯誤代碼為WSAEWOULDBLOCK,則您的應用程序可以:1.用select(),通過檢查套接口是否可寫,來確定連接請求是否完成。或者,2.如果您的應用程序使用基于消息的WSAAsynSelect()來表示對連接事件的興趣,則當連接操作完成后,您會收到一個FD_CONNECT消息。錯誤代碼:WSAENOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。WSAEADDRINUSE:所指的地址已在使用中。WSAEINTR:通過一個WSACancelBlockingCall()來取消一個(阻塞的)調用。WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。WSAEADDRNOTAVAIL:在本地機器上找不到所指的地址。WSAENOTSUPPORT:所指族中地址無法與本套接口一起使用。WSAECONNREFUSED:連接嘗試被強制拒絕。WSAEDESTADDREQ:需要目的地址。WSAEFAULT:namelen參數不正確。WSAEINVAL:套接口沒有準備好與一地址捆綁。WSAEISCONN:套接口早已連接。WSAEMFILE:無多余文件描述字。WSAENETUNREACH:當前無法從本主機訪問網絡。WSAENOBUFS:無可用緩沖區。套接口未被連接。WSAENOTSOCK:描述字不是一個套接口。WSAETIMEOUT:超時時間到。listen():創建一個套接口并監聽申請的連接.語法:intPASCALFARlisten(SOCKETs,intbacklog);參數:S:用于標識一個已捆綁未連接套接口的描述字。backlog:等待連接隊列的最大長度。注釋:為了接受連接,先用socket()創建一個套接口,然后用listen()為申請進入的連接建立一個后備日志,然后便可用accept()接受連接了。listen()僅適用于支持連接的套接口,如SOCK_STREAM類型的。套接口s處于一種“變動”模式,申請進入的連接請求被確認,并排隊等待被接受。這個函數特別適用于同時有多個連接請求的服務器;如果當一個連接請求到來時,隊列已滿,那么客戶將收到一個WSAECONNREFUSED錯誤。當沒有可用的描述字時,listen()函數仍試圖正常地工作。它仍接受請求直至隊列變空。當有可用描述字時,后續的一次listen()或accept()調用會將隊列按照當前或最近的“后備日志”重新填充,如有可能的話,將恢復監聽申請進入的連接請求。返回值:如無錯誤發生,listen()返回0。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。錯誤代碼:WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。WSAEADDRINUSE:試圖用listen()去監聽一個正在使用中的地址。WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。WSAEINVAL:該套接口未用bind()進行捆綁,或已被連接。WSAEISCONN:套接口已被連接。WSAEMFILE:無可用文件描述字。WSAENOBUFS:無可用緩沖區空間。WSAENOTSOCK:描述字不是一個套接口。WSAEOPNOTSUPP:該套接口不正常listen()調用。socket():建立Socket,此函數用來建立一個Socket描述字,并為此Socket建立其所使用的資源。語法:SOCKETPASCALFARsocket(intaf,inttype,intprotocol)參數:af:目前只提供PF_INET(AF_INET);type:Socket的類型(SOCK_STREAM、SOCK_DGRAM);protocol:通訊協定(如果使用者不指定則設為0);注釋:如果要建立的是遵從TCP/IP協議的socket,第二個參數type應為SOCK_STREAM,如為UDP(數據報)的socket,應為SOCK_DGRAM。recv():從一個套接口接收數據。語法:intPASCALFARrecv(SOCKETs,charFAR*buf,intlen,intflags);參數:s:一個標識已連接套接口的描述字。buf:用于接收數據的緩沖區。len:緩沖區長度。flags:指定調用方式。注釋:本函數用于已連接的數據報或流式套接口s進行數據的接收。對SOCK_STREAM類型的套接口來說,本函數將返回所有可用的信息,最大可達緩沖區的大小。如果套接口被設置為線內接收帶外數據(選項為SO_OOBINLINE),且有帶外數據未讀入,則返回帶外數據。應用程序可通過調用ioctlsocket()的SOCATMARK命令來確定是否有帶外數據待讀入。對于數據報類套接口,隊列中第一個數據報中的數據被解包,但最多不超過緩沖區的大小。如果數據報大于緩沖區,那么緩沖區中只有數據報的前面部分,其他的數據都丟失了,并且recv()函數返回WSAEMSGSIZE錯誤。如果沒有數據待讀,那么除非是非阻塞模式,不然的話套接口將一直等待數據的到來,此時將返回SOCKET_ERROR錯誤,錯誤代碼是WSAEWOULDBLOCK。用select()或WSAAsynSelect()可以獲知何時數據到達。如果套接口為SOCK_STREAM類型,并且遠端“優雅”地中止了連接,那么recv()一個數據也不讀取,立即返回。如果立即被強制中止,那么recv()將以WSAECONNRESET錯誤失敗返回。在套接口的所設選項之上,還可用標志位flag來影響函數的執行方式。也就是說,本函數的語義既取決于套接口選項,也取決于標志位參數。標志位可取下列值:MSG_PEEK查看當前數據。數據將被復制到緩沖區中,但并不從輸入隊列中刪除。MSG_OOB處理帶外數據(參見2.2.3節具體討論)。返回值:若無錯誤發生,recv()返回讀入的字節數。如果連接已中止,返回0。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。錯誤代碼:WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。WSAENOTCONN:套接口未連接。WSAEINTR:阻塞進程被WSACancelBlockingCall()取消。WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。WSAENOTSOCK:描述字不是一個套接口。WSAEOPNOTSUPP:指定了MSG_OOB,但套接口不是SOCK_STREAM類型的WSAESHUTDOWN:套接口已被關閉。當一個套接口以0或2的how參數調用shutdown()關閉后,無法再用recv()接收數據。WSAEWOULDBLOCK:套接口標識為非阻塞模式,但接收操作會產生阻塞。WSAEMSGSIZE:數據報太大無法全部裝入緩沖區,故被剪切。WSAEINVAL:套接口未用bind()進行捆綁。WSAECONNABORTED:由于超時或其他原因,虛電路失效。WSAECONNRESET:遠端強制中止了虛電路。send():向一個已連接的套接口發送數據。語法:intPASCALFARsend(SOCKETs,constcharFAR*buf,intlen,intflags);參數:s:一個用于標識已連接套接口的描述字。buf:包含待發送數據的緩沖區。len:緩沖區中數據的長度。flags:調用執行方式。注釋:send()適用于已連接的數據報或流式套接口發送數據。對于數據報類套接口,必需注意發送數據長度不應超過通訊子網的IP包最大長度。IP包最大長度在WSAStartup()調用返回的WSAData的iMaxUdpDg元素中。如果數據太長無法自動通過下層協議,則返回WSAEMSGSIZE錯誤,數據不會被發送。請注意成功地完成send()調用并不意味著數據傳送到達。如果傳送系統的緩沖區空間不夠保存需傳送的數據,除非套接口處于非阻塞I/O方式,否則send()將阻塞。對于非阻塞SOCK_STREAM類型的套接口,實際寫的數據數目可能在1到所需大小之間,其值取決于本地和遠端主機的緩沖區大小。可用select()調用來確定何時能夠進一步發送數據。在相關套接口的選項之上,還可通過標志位flag來影響函數的執行方式。也就是說,本函數的語義既取決于套接口的選項也取決于標志位。后者由以下一些值組成:MSG_DONTROUTE指明數據不選徑。一個WINDOWS套接口供應商可以忽略此標志;參見2.4節中關于SO_DONTROUTE的討論。MSG_OOB發送帶外數據(僅適用于SO_STREAM;參見2.2.3節)。返回值:若無錯誤發生,send()返回所發送數據的總數(請注意這個數字可能小于len中所規定的大小)。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。錯誤代碼:WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。WSAEACESS:要求地址為廣播地址,但相關標志未能正確設置。WSAEINTR:通過一個WSACancelBlockingCall()來取消一個(阻塞的)調用。WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。WSAEFAULT:buf參數不在用戶地址空間中的有效位置。WSAENETRESET:由于WINDOWS套接口實現放棄了連接,故該連接必需被復位。WSAENOBUFS:WINDOWS套接口實現報告一個緩沖區死鎖。WSAENOTCONN:套接口未被連接。WSAENOTSOCK:描述字不是一個套接口。WSAEOPNOTSUPP:已設置了MSG_OOB,但套接口非SOCK_STREAM類型。WSAESHUTDOWN:套接口已被關閉。一個套接口以1或2的how參數調用shutdown()關閉后,無法再用sned()函數。WSAEWOULDBLOCK:WSAEMSGSIZE:套接口為SOCK_DGRAM類型,且數據報大于WINDOWS套接口實現所支持的最大值。WSAEINVAL:套接口未用bind()捆綁。WSAECONNABORTED:由于超時或其他原因引起虛電路的中斷。WSAECONNRESET:虛電路被遠端復位。WSAAsyncSelect():通知套接口有請求事件發生.語法:intPASCALFARWSAAsyncSelect(SOCKETs,HWNDhWnd,unsignedintwMsg,longlEvent);參數:s標識一個需要事件通知的套接口的描述符.hWnd標識一個在網絡事件發生時需要接收消息的窗口句柄.wMsg在網絡事件發生時要接收的消息.lEvent位屏蔽碼,用于指明應用程序感興趣的網絡事件集合.注釋:本函數用來請求WindowsSocketsDLL為窗口句柄發一條消息-無論它何時檢測到由lEvent參數指明的網絡事件.要發送的消息由wMsg參數標明.被通知的套接口由s標識.本函數自動將套接口設置為非阻塞模式.lEvent參數由下表中列出的值組成.值意義FD_READ欲接收讀準備好的通知.FD_WRITE欲接收寫準備好的通知.FD_OOB欲接收帶邊數據到達的通知.FD_ACCEPT欲接收將要連接的通知.FD_CONNECT欲接收已連接好的通知.FD_CLOSE欲接收套接口關閉的通知.啟動一個WSAAsyncSelect()將使為同一個套接口啟動的所有先前的WSAAsyncSelect()作廢.例如,要接收讀寫通知,應用程序必須同時用FD_READ和FD_WRITE調用WSAAsyncSelect(),如下:rc=WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE);對不同的事件區分不同的消息是不可能的.下面的代碼將不會工作;第二個調用將會使第一次調用的作用失效,只有FD_WRITE會通過wMsg2消息通知到.rc=WSAAsyncSelect(s,hWnd,wMsg1,FD_READ);rc=WSAAsyncSelect(s,hWnd,wMsg2,FD_WRITE);如果要取消所有的通知,也就是指出WindowsSockets的實現不再在套接口上發送任何和網絡事件相關的消息,則lEvent應置為0.rc=WSAAsyncSelect(s,hWnd,0,0);盡管在本例中,WSAAsyncSelect()立即使傳給該套接口的事件消息無效,仍有可能有消息等在應用程序的消息隊列中.應用程序因此也必須仍準備好接收網絡消息-即使消息作廢.用closesocket()關閉一個套接口也同樣使WSAAsyncSelect()發送的消息作廢,但在closesocke()之前隊列中的消息仍然起作用.由于一個已調用accept()的套接口和用來接收它的偵聽套接口有同樣的屬性,任何為偵聽套接口設置的的WSAAsyncSelect()事件也同樣對已接收的套接口起作用.例如,如果一個偵聽的套接口有WSAAsyncSelect()事件FD_ACCEPT,FD_READ,FD_WRITE,則任何在那個偵聽的套接口上接收的套接口將也有FD_ACCEPT,FD_READ,FD_WRITE事件,以及同樣的wMsg的值.若需要不同的wMsg及事件,應用程序應調用WSAAsyncSelect(),將已接收的套接口和想要發送的新消息作為參數傳遞.當某一套接口s上發生了一個已命名的網絡事件,應用程序窗口hWnd會接收到消息wMsg.wParam參數標識了網絡事件發生的套接口.lParam的低字指明了發生的網絡事件.lParam的高字則含有一個錯誤代碼.該錯誤代碼可以是winsock.h中定義的任何錯誤.錯誤代碼和事件可以通過WSAGETSELECTERRORH和WSAGETSELECTEVENT宏從lParam中取出.定義如下:#defineWSAGETSELECTERROR(lParam)HIWORD(lParam)#defineWSAGETSELECTEVENT(lParam)LOWORD(lParam)注意:在accept()調用和為改變事件或wMsg的WSAAsyncSelect()調用中有一個計時窗口.應用程序如果需要給偵聽的和調用過accept()的套接口以不同的wMsg,它就應該在偵聽的套接口上請求FD_ACCEPT事件,然后在accept()調用后設置相應的事件.由于FD_ACCEPT從不發送給已連接的套接口,而FD_READ,FD_WRITE,FD_OOB及FD_CLOSE也從不發送給偵聽套接口,所以不會產生困難.使用以上的宏將最大限度的提高應用程序的可移植性.返回的可能網絡事件如下:值意義FD_READ套接口s準備讀FD_WRITE套接口s準備寫FD_OOB帶外數據準備好在套接口s上讀.FD_ACCEPT套接口s準備接收新的將要到來的連接.FD_CONNECT套接口s上的連接完成.FD_CLOSE由套接口s標識的連接已關閉.返回值:0若應用程序感興趣的網絡事件的聲明成功.SOCKET_ERROR否則.可通過調用WSAGetLastError()返回特定的錯誤代碼.錯誤代碼:WSANOTINITIALISED在使用本API前必須進行一次成功的WSAStartup()調用.WSAENETDOWNWINDOWSSOCKETS實現已檢測到網絡子系統故障.WSAEINVAL指出指定的參數之一是非法的.WSAEINPROGRESS一個阻塞的WindowsSockets操作正在進行.附加的錯誤代碼可能在應用程序窗口接收到消息時被置.這些代碼可以用WSAGETSELECTERROR宏從lParam中取出.對應于每個網絡事件的可能錯誤代碼為:事件:FD_CONNECTWSAEADDRINUSE給定的地址已被使用.WSAEADDRNOTAVAIL指定的地址在本地機器不能使用.WSAEAFNOSUPPORT指定族的地址不能和本套接口同時使用.WSAECONNREFUSED連接的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 三年級上美術教學設計-幸福樂園-湘美版
- 2024年五年級數學上冊 五 多邊形面積的計算 2三角形的面積教學設計 西師大版
- 20陀螺教學設計-2024-2025學年四年級上冊語文統編版
- Module 10 教學設計 2023-2024學年外研版七年級英語下冊
- 關系營銷企業內部關系
- 競憑幼兒園園長述職報告
- 2024-2025學年高中生物 第1章 第4節 基因工程的發展前景教學設計 浙科版選修3
- 2024六年級語文下冊 第二單元 習作:寫作品梗概教學設計 新人教版
- 七年級英語下冊 Module 3 Making plans Unit 1 What are you going to do at the weekends第1課時教學設計(新版)外研版
- 2024-2025學年高中化學 第一章 第二節 原子結構與元素的性質 第2課時 元素周期律(一)教學設計 新人教版選修3
- 2024年江蘇省泰州市保安員理論考試題庫及答案(完整)
- 專題01《水銀花開的夜晚》 高考語文二輪復習
- 送達地址確認書(訴訟類范本)
- 爵士音樂 完整版課件
- 嘉興華雯化工 - 201604
- 冀教版七年級下冊數學課件 第8章 8.2.1 冪的乘方
- XX公司“十四五”戰略發展規劃及年度評價報告(模板)
- 計算機輔助設計(Protel平臺)繪圖員級試卷1
- 除法口訣表(完整高清打印版)
- 河北省城市建設用地性質和容積率調整管理規定---精品資料
- 講課實錄-洛書時間數字分析法
評論
0/150
提交評論