Socket編程基礎_第1頁
Socket編程基礎_第2頁
Socket編程基礎_第3頁
Socket編程基礎_第4頁
Socket編程基礎_第5頁
已閱讀5頁,還剩52頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Socket 編程基礎 套接字的概念與編程原理 Winsock API基本函數(shù)套接口與連接的建立 Winsock API基本函數(shù)數(shù)據(jù)傳輸 Winsock API基本函數(shù)套接口與連接的關閉 面向連接的客戶/服務器程序工作流程以及舉例 無連接的客戶/服務器程序工作流程以及舉例Socket編程接口來源 Socket編程接口是對TCP/IP協(xié)議的一種封裝Socket本身并不是協(xié)議,而是一個調用接口(API),通過Socket,我們才能使用TCP/IP協(xié)議。 加利福尼亞大學伯克利分校為UNIX系統(tǒng)開發(fā)出了伯克利套接字(BSD socket),在此基礎上擴展形成了windows套接字。套接口的概念套接口的

2、概念程序A基于TCP/IP的網(wǎng)絡程序B網(wǎng)絡管理軟件網(wǎng)絡接口卡(NIC)主機A主機B套接口套接口套接口的本質 通信過程中所要使用一些緩沖區(qū)和一些相關的數(shù)據(jù)結構 在TCP/IP協(xié)議中,“IP地址+TCP或UDP端口號”唯一標識網(wǎng)絡通訊中的一個進程,“IP地址+端口號”就稱為socket。 在TCP協(xié)議中,建立連接的兩個進程各自有一個socket來標識,那么這兩個socket組成的socket pair就唯一標識一個連接。Socket的服務方式和類型 流式套接口(SOCK_STREAM) 數(shù)據(jù)報套接口(SOCK_DGRAM) 原始套接口(SOCK_RAW) 比較項目流式套接字數(shù)據(jù)報式套接字建立和釋放

3、連接建立和釋放連接保證數(shù)據(jù)到達保證數(shù)據(jù)到達按發(fā)送順序接收數(shù)據(jù)按發(fā)送順序接收數(shù)據(jù)通訊數(shù)據(jù)包含完整的目的地通訊數(shù)據(jù)包含完整的目的地址信息址信息原始套接字 原始套接字是公開的套接字編程接口,使用它可以在IP層上對套接字進行編程,發(fā)送和接收IP層上的原始數(shù)據(jù)包。 ICMP、TCP和UDP等協(xié)議的數(shù)據(jù)包。網(wǎng)絡字節(jié)順序 不同的主機對字節(jié)值的存儲順序不同。 在存儲由多個字節(jié)組成的一個字時,計算機在起始地址處存放整數(shù)的低序號字節(jié),這種存儲格式叫“小序在前”(Little-endian); 在存儲由多個字節(jié)組成的一個字時,計算機在起始地址處存放整數(shù)的高序號字節(jié),這種存儲格式叫“大序在前”(Big-endian)

4、。網(wǎng)絡字節(jié)順序 在計算機中,TCP/IP協(xié)議使用的16位整數(shù)(如端口號)和32位整數(shù)(如IP地址)是按計算機各自的“主機字節(jié)”(Host-byte)來表示的。 在網(wǎng)絡中,為了保證數(shù)據(jù)的正確性,網(wǎng)絡通信協(xié)議中必須指定網(wǎng)絡字節(jié)順序。如果在網(wǎng)絡中使用IP地址和端口號,按“互聯(lián)網(wǎng)聯(lián)網(wǎng)標準”的要求,指定的多字節(jié)值必須用“大序在前”的形式來表示,一般稱之為“網(wǎng)絡字節(jié)”(Network-byte)順序。 4個API函數(shù) htonl():參數(shù)是主機字節(jié)順序的一個4字節(jié)數(shù),函數(shù)返回網(wǎng)絡字節(jié)順序的數(shù); WSAHtonl():參數(shù)是主機字節(jié)順序的一個4字節(jié)數(shù),函數(shù)返回網(wǎng)絡字節(jié)順序的數(shù); htons():參數(shù)是主機字

5、節(jié)順序的一個2字節(jié)數(shù),函數(shù)返回網(wǎng)絡字節(jié)順序的數(shù); WSAHtons():參數(shù)是主機字節(jié)順序的一個2字節(jié)數(shù),函數(shù)返回網(wǎng)絡字節(jié)順序的數(shù)。sockaddr結構體 通用結構,用來保存socket信息struct sockaddr u_short sa_family;charsa_data14;sockaddr_in結構體 指定IPv4地址結構struct sockaddr_in shortsin_family;u_shortsin_port;structin_addr sin_addr;charsin_zero8;in_addr結構體IP地址常用點分法來表示: 192.168.0.1計算機中使用無符號

6、長整數(shù)(unsigned long)來存儲和表示IP地址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;#define s_addr S_un.S_addr#define s_host S_un.S_un_b.s_b2#define s_net S_un.S_un_b.s_b1#define s_imp S_un.S_un_w.s_w2#define s_impno S_un.S_un_b.s_b4#define

7、 s_lh S_un.S_un_b.s_b3;inet_addr() 將點分法IP地址字符串轉換為in_addr結構體中的IP地址格式:unsigned long inet_addr( const char* cp );參數(shù)cp表示點分法IP地址字符串。如果調用inet_addr()函數(shù)時沒有出現(xiàn)錯誤,則函數(shù)返回unsignedlong類型的網(wǎng)絡字節(jié)順序格式IP地址;如果參數(shù)cp不是有效的IP地址字符串,則inet_addr()函數(shù)返回INADDR_NONE。inet_ntoa() 將in_addr結構體中的IP地址轉換為點分法IP地址字符串 char FAR* inet_ntoa(struc

8、t in_addr in); 參數(shù)in是in_addr結構體類型,表示要進行轉換的IP地址,返回結果為char*類型的IP地址。sa_familysa_datasockaddr結構體s_b1s_b2s_b3s_b4s_w1s_w2S_addrin_addr結構體sin_familysin_portsin_addrsin_zerosockaddr_in結構體Winsock版本 WinSock1和WinSock2。平臺WinSock版本W(wǎng)indows 951 . 1(2 . 2)Windows 982 . 2Windows NT 4.02 . 2Windows 20002 . 2Windows X

9、P2 . 2 套接字的概念與編程原理 Winsock API基本函數(shù)套接口與連接的建立 Winsock API基本函數(shù)數(shù)據(jù)傳輸 Winsock API基本函數(shù)套接口與連接的關閉 面向連接的客戶/服務器程序工作流程以及舉例 無連接的客戶/服務器程序工作流程以及舉例Winsock2的使用 通常使用WinSock 2.2實現(xiàn)網(wǎng)絡通信的功能,則需要引用頭文件winsock2.h和庫文件ws2_32.lib,代碼如下: #include #pragma comment(lib, ws2_32.lib) 告訴連接器連接的時候要找ws2_32.lib WSAStartup函數(shù) 作用:啟動win_socket

10、的dll庫,初始化winsock所對應的ws2_32.dll,完成套接字初始化 加載WinSock DLL的相應版本int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData);返回一個WSADATA結構WinSock庫的版本高位字節(jié)指定副版本號低位字節(jié)指定主版本號可以用宏MAKEWORD(X, Y) 方便地設置WSACleanup() 中止Windows Sockets DLL的使用 ,卸載所加載的庫 int WSACleanup (void); 返回值 成功:返回0 失敗:返回SOCKET_ERROR.WSAGetLastErr

11、or() 調用任何一個WinSock函數(shù)之后可用WSAGetLastError函數(shù)來獲得詳細的錯誤代碼 int WSAGetLastError (void); 返回值 :詳細的錯誤代碼不成功的Winsock函數(shù)調用返回的最常見的值是宏定義SOCKET_ERROR WSAStartup()函數(shù)調用失敗能不能用WSAGetLastError()獲取詳細錯誤代碼? 通常依靠應用程序調用WSAGetLastError()機制獲得的錯誤代碼是不能使用的,因為Windows Sockets DLL可能沒有建立“上一錯誤”信息儲存的客戶數(shù)據(jù)區(qū)域。 Socket()或WSASocket()Winsock 1中

12、提供的創(chuàng)建套接口函數(shù)的格式: SOCKET socket(int af, int type, int protocol );在Winsock 2中提供的該函數(shù)的擴展格式SOCKET WSASocket( int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, Group g, int iFlags);創(chuàng)建一個流套接字三種格式 SOCKET sockid=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); SOCKET sockid=WSASocket(AF_INET,SOCK_STREA

13、M,0);SOCKET sockid=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED); 創(chuàng)建一個數(shù)據(jù)報套接口 SOCKET sockid=socket(AF_INET,SOCK_GDRAM,IPPROTO_UDP); 創(chuàng)建一個原始套接口 SOCKET sockid=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); 指定本地地址bind()函數(shù)int bind(SOCKET s,const struct sockaddr FAR* name,int namelen);把一個套接口與一個主機地址和端

14、口號聯(lián)系起來socket()套接字IP地址端口sockaddr_in結構體bind()、connect()綁定了IP地址/端口的套接字監(jiān)聽連接listen()listen(函數(shù)格式:int listen(SOCKET s, int backlog ); s:標識一個已綁定地址,未建立連接套 接字。backlog:指定正在等待連接的最大隊列長度。請求連接connect()或WSAConnect()Winsock 1中提供的connect()函數(shù):int connect(SOCKET s,const struct sockaddr FAR* name,int namelen );Winsock 2

15、中提供的擴展格式是: int WSAConnect( SOCKET s,const struct sockaddr FAR* name,int namelen,LPWSABUF lpCallerData,LPWSABUF lpCalleeData, LPQOS lpSQOS,LPQOS lpGQOS); S:將要建立連接的套接口描述字。 name:是一個指向遠端套接口地址結構(sockaddr_in)的指針,表示s套接口欲與其建立一條連接。 namelen:name名字的長度。接受連接accept()或WSAAccept() Winsock 1提供的accept()函數(shù)的格式:SOCKET a

16、ccept(SOCKET s,struct sockaddr FAR* addr,int FAR* addrlen); Winsock 2提供的accept()函數(shù)的擴展格式:SOCKET WSAAccept(SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen,LPCONDITIONPROC lpfnCondition,DWORD dwCallbackData ); s:標識一個套接口描述字,該套接口處于監(jiān)聽連接的狀態(tài)。 addr:是一個地址結構的指針,用來存放發(fā)出連接請求的那個客戶機的IP地址信息。addr參數(shù)的實際格式由套接口創(chuàng)建

17、時所使用的地址族確定。 addrlen:該參數(shù)指出客戶套接口地址結構的長度。 該函數(shù)就返回一個新的套接口字,它對應于已經接受的那個客戶機的連接。對該客戶機后續(xù)的所有操作,都使用這個新的套接字,成為已連接套接字(Connected Socket)。 原來那個監(jiān)聽套接字仍然用于接收其他客戶機發(fā)送的連接請求,仍處于監(jiān)聽模式,因此把它叫監(jiān)聽套接字(Listening Socket)。 套接字的概念與編程原理 Winsock API基本函數(shù)套接口與連接的建立 Winsock API基本函數(shù)數(shù)據(jù)傳輸 Winsock API基本函數(shù)套接口與連接的關閉 面向連接的客戶/服務器程序工作流程以及舉例 無連接的客戶

18、/服務器程序工作流程以及舉例在已建立連接的套接口上發(fā)送數(shù)據(jù)send()或WSASend()在Winsock 1中提供的格式: Int send(SOCKET s, const char FAR* buf, int len, int flags); 在Winsock 2中提供的WSASend()函數(shù)的擴展格式: int WSASend(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOV

19、ERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); s:用于標識已建立連接的套接口描述字。 buf:它是一個字符緩沖區(qū),內有將要發(fā)送的數(shù)據(jù)。 len:即將發(fā)送的緩沖區(qū)中的字符數(shù)。 flags:用于控制數(shù)據(jù)傳輸方式,它可以是0、宏定義MSG_DONTROUTE或MSG_OOB。 0表示按正常方式發(fā)送數(shù)據(jù); MSG_DONTROUTE標志說明系統(tǒng)目標主機就在直接連接的本地網(wǎng)絡中,無需路由選擇,但如果傳輸協(xié)議的實現(xiàn)不支持該選項,則該標志被忽略; MSG_OOB標志指出數(shù)據(jù)是按帶外數(shù)據(jù)發(fā)送的。在已建立連接的套接口上接收數(shù)據(jù)recv()或WSARecv()

20、在Winsock 1中提供的recv()函數(shù)的格式是: int recv(SOCKET s, char FAR* buf, int len, int flags); 在Winsock 2中提供的WSARecv()函數(shù)擴展格式是:int WSARecv(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPINT lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionR

21、outine); s:已建立連接的套接口描述字。 buf:用于接收數(shù)據(jù)的緩沖區(qū)。 len:緩沖區(qū)長度。 flags:指定調用方式。flags參數(shù)可以是下面的值:0、MSG_PEEK或MSG_OOB。 0 表 示 接 收 的 是 正 常 數(shù) 據(jù) , 無 特 殊 行 為 。MSG_PEEK表示會使有用的數(shù)據(jù)復制到所提供的接收端緩沖區(qū)內,但是沒有從系統(tǒng)緩沖區(qū)中將數(shù)據(jù)刪除。 MSG_OOB標志表示處理帶外數(shù)據(jù)。在無連接的套接口上接收數(shù)據(jù)recvfrom()或WSARecvFrom()Winsock 1中提供的recvfrom()函數(shù)的格式:int recvfrom(SOCKET s,char FAR*

22、 buf,int len, int flags, struct sockaddr FAR* from,int FAR* fromlen);Winsock 2中提供的WSARecvFrom()函數(shù)的擴展格式:int WSARecvFrom(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPINT lpFlags,LPVOID lpFrom,LPINT lpFromlen,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_RO

23、UTINElpCompletionRoutine ); s:標識一個套接口的描述字; buf:接收數(shù)據(jù)緩沖區(qū); len:緩沖區(qū)長度; flags:調用操作方式,同recv()中的flags; from:(可選)指針,指向裝有源地址的緩沖區(qū),對監(jiān)聽套 接 字 的 具 體 協(xié) 議 來 說 , f r o m 參 數(shù) 是 一 個 指 向SOCKADDR結構的指針,它的長度由指針fromlen指向的數(shù)確定,這個API調用返回數(shù)據(jù)時,SOCKADDR結構內便填入發(fā)送數(shù)據(jù)的那個工作站的地址; fromlen:(可選)指針,指向from緩沖區(qū)長度值; 在無連接的套接口上發(fā)送數(shù)據(jù)sendto()或WSASen

24、dTo()Winsock 1中提供的sendto()函數(shù)的格式:int sendto(SOCKET s, const char FAR* buf, int len, int flags, const struct sockaddr FAR* to, int tolen);Winsock 2中提供的WSASendTo()函數(shù)的擴展格式: int WSASendTo(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesSent,int iFlags,LPVOID lpTo,int iToLen, LPWSAO

25、VERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); s:一個標識套接口的描述字; buf:待發(fā)送數(shù)據(jù)的緩沖區(qū); len:指明buf緩沖區(qū)中要發(fā)送的數(shù)據(jù)長度; flags:調用方式標志位,同send()中該參數(shù)的含義相同; to:指針,指向接收數(shù)據(jù)的目的套接口的地址;tolen:to所指地址的長度 套接字的概念與編程原理 Winsock API基本函數(shù)套接口與連接的建立 Winsock API基本函數(shù)數(shù)據(jù)傳輸 Winsock API基本函數(shù)套接口與連接的關閉 面向連接的客戶/服務器程序

26、工作流程以及舉例 無連接的客戶/服務器程序工作流程以及舉例關閉讀寫通道shutdown() shutdown()函數(shù)的格式:int shutdown( SOCKET s, int how );s:標識一個套接口的描述字;how:用于描述禁止哪些操作標志關閉方式對應的參數(shù)值說 明SD_RECEIVE0表示不允許再調用接收函數(shù),它關閉讀通道。套接口接收緩沖區(qū)中的所有數(shù)據(jù)都被丟失,并且有新數(shù)據(jù)到達套接口時,也被 TCP 協(xié)議層丟失,但它對發(fā)送緩沖區(qū)沒有影響,進程仍然可以在套接口上發(fā)送數(shù)據(jù)SD_SEND1表示不允許再調用發(fā)送函數(shù),它關閉寫通道。在套接口發(fā)送緩沖區(qū)中的數(shù)據(jù)都被發(fā)送出去,得到接收端確認之后

27、,就生成一個 FIN 包關閉連接。但它對接收緩沖區(qū)沒有影響,進程仍然可以在套接口上接收數(shù)據(jù)SD_BOTH2關閉讀寫通道,相當于執(zhí)行了上面 SD_RECEIVE 和 SD_SEND 兩個命令關閉套接口closesocket() 一個套接口不再使用時一定要關閉這個套接口,以釋放與該套接口關聯(lián)的所有資源,包括等候處理的數(shù)據(jù)。 closesocket()函數(shù)的格式如下: int closesocket(SOCKET s); 套接字的概念與編程原理 Winsock API基本函數(shù)套接口與連接的建立 Winsock API基本函數(shù)數(shù)據(jù)傳輸 Winsock API基本函數(shù)套接口與連接的關閉 面向連接的客戶/

28、服務器程序工作流程以及舉例 無連接的客戶/服務器程序工作流程以及舉例WSAStartup()socket()bind()listen()accept()等待客戶連接請求的到來recv()send()closesocket()WSACleanup()用三次握手過程建立TCP連接send()recv()closesocket()WSACleanup()關閉TCP連接交換數(shù)據(jù)交換數(shù)據(jù)connect()socket()WSAStartup()面向連接的客戶面向連接的客戶/服務器程序工作模型服務器程序工作模型面向連接的面向連接的服務器端程序調試環(huán)境:Visual C+6.0服務器IP地址:由系統(tǒng)指定服務

29、器端口號:5050程序名稱:server.cpp程序功能:服務器端的程序當有客戶提出連接請求時,在端口5050與客戶端進行TCP連接,連接成功后,顯示客戶IP地址和端口號,并給客戶端發(fā)送 Hello! I am a server.字符串。如果發(fā)送正確則顯示所發(fā)送的字節(jié)數(shù)命令格式:server面向連接的客戶面向連接的客戶端程序調試環(huán)境:VC+6.0程序名稱:client.cpp客戶IP地址和端口:由系統(tǒng)指定程序功能:客戶端程序向服務器提出TCP連接的請求,當連接建立后,從服務器的端口5050接收數(shù)據(jù)并進行顯示,然后斷開與服務器的連接命令格式:client 服務器IP地址命令舉例:client 192.168.0.1說 明 : 上 面 設 將 要 連 接 的 服 務 器 I P 地 址 為192.168.0.1,端口號為5050面向連接的通信過程中五元組的建立五元組服務器端五元組 由socket()確定由服務器端調用bind()時確定由accept()確定客戶端五元組由socket()確定由客戶端的bind()調用確定。 如果客戶端沒有進行bind()調用, 或調用了 bind()但沒有指定具體地址或端口,則由系統(tǒng)內核自動確定地址和端口由connect()確定 套接字的概念與編程原理 Winsock API基本函數(shù)套接口與連接的建立 Winsock

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論