1? 計算機網絡
? ? ? ? 計算機網絡,是指將地理位置不同的具有獨立功能的多臺計算機及其外部設備,通過通信線路連接起來,在網絡操作系統、網絡管理軟件及網絡通信協議的管理和協調下,實現資源共享和信息傳遞的計算機系統。
? ? ? ? 網絡協議是一種特殊的軟件,是計算機網絡實現其功能的最基本的機制。網絡協議的本質就是規則,即各種硬件和軟件必須遵循的共同守則。網絡協議并不是一套單獨的軟件,它融合于其他所有的軟件甚至硬件系統中,因此可以說協議在網絡中無所不在。
? ? ? ? 為了減少網絡設計的復雜性,絕大多數網絡采用分層設計的方法。所謂分層設計,就是按照信息的流動過程將網絡的整體功能分解為一個個的功能層,不同機器上的同等功能層之間采用相同的協議,同一機器上的相鄰功能層之間通過接口進行信息傳遞。各層的協議和結構統稱為協議棧。
? ? ? ? 描述計算機網絡各協議層的一般方法是采用國際標準化組織(International Standardization Organization)的計算機通信開放系統互聯(Open System Interconnection)模型,簡稱ISO/OSI網絡協議模型:
????????
????????
TCP/IP:
????????TCP/IP不是個單一的網絡協議,而是由一組具有層次關系的網絡協議組成的協議家族,簡稱TCP/IP協議族:
? ? ? ? TCP:傳輸控制協議,面向連接,可靠的全雙工的字節流
? ? ? ? UDP:用戶數據報協議,無連接,不如TCP可靠但速度快
? ? ? ? ICMP:網際控制消息協議,處理路由器和主機間的錯誤和控制消息
? ? ? ? IGMP:網際組管理協議,用于多播
? ? ? ? IPv4:網際協議版本4,使用32位地址,為TCP、UDP、ICMP、IGMP提供遞送分組服務
? ? ? ? IPv6:網際協議版本6,使用128位地址,為TCP、UDP、ICMPv6提供遞送分組服務
? ? ? ? ARP:地址解析協議,把IPv4地址映射到硬件地址
? ? ? ? RARP:逆地址解析協議,把硬件地址映射到IPv4地址
? ? ? ? ICMPv6:網際控制消息協議版本6,總和了ICMP、IGMP、ARP的功能
? ? ? ? BPF:BSD分組過濾器,為應用程序提供訪問數據鏈路層的接口,由源自BSD的系統內核
? ? ? ? ? ? ? ? ? ?提供
? ? ? ? DLPI:數據鏈路提供者接口,為應用程序提供訪問數據鏈路層的接口,由源自SVR4的系統
? ? ? ? ? ? ? ? ? ? 內核提供
????????
? ? ? ? 在ISO/OSI網絡協議模型的基礎上,TCP/IP協議做了部分合并和簡化,同時將網絡編程的接口設定在傳輸層與會話層之間,這樣做的理由有二:
? ? ? ? 1)上三層與應用程序的業務邏輯(如數據包的組織與解析、收發的時機與次序等)密切相關,而與具體的通信細節(如收發分組、等待確認、分組排序、計算驗證校驗、丟包重傳等)關系不大;下四層主要處理通信細節而與具體應用的業務邏輯無關。
? ? ? ? 2)上三層通常構成用戶進程,而下四層通常是系統內核的一部分。
????????
消息包和消息流:
? ? ? ? 應用程序負責組織的通常都是與業務相關的數據內容,而要想把這些數據內容通過網絡發送出去,就要將其自上而下地壓入協議棧,每經歷一個協議層,就會對數據做一層封包,每一層輸出的封包都是下一層輸入的內容,消息包沿著協議棧的運動形成了消息流。
? ? ? ? 當從網絡上接收數據時,過程剛好相反,消息包自下而上地流經協議棧,每經歷一個協議層,就會對輸入的數據解一層封包,經過層層解包以后,應用程序最終得到的將只是與業務相關的數據內容。數據的封裝和解析過程:
????????
2? IP地址
? ? ? ? IP地址,全稱網際協議地址(Internet Protocol Address),是IP協議提供的一種統一的地址格式,為互聯網上的每個網絡和每臺主機分配一個邏輯地址,借以消除物理地址差異性所帶來的影響。
????????百度查到是公網IP:106.222.188.106? ?,包含若干私網IP
????????ifconfig查是私網IP:192.168.221.68
? ? ? ? 在計算機內部,IP地址用一個32位的無符號整數表示,如:0x01020304
? ? ? ? 人們更習慣使用點分十進制字符串表示,如:1.2.3.4。字符串形式的從左到右,對應整數形式的高字節到低字節。注意這里所說的高低指的是數位高低而非地址高低。
? ? ? ? IP地址分級:
? ? ? ? A級地址:以0為首的8位網絡地址? ? ? ? +24位本地地址
? ? ? ? B級地址:以10為首的16位網絡地址? ? +16位本地地址
? ? ? ? C級地址:以110為首的24為網絡地址? +8位本地地址
? ? ? ? D級地址:以1110為首的32位多播地址
? ? ? ? 如某計算機的IP地址:192.168.182.48是C級地址,網絡地址192.168.182.0,本地地址48。
? ? ? ? 借助子網掩碼可以快速幫我們確定IP地址的網絡地址和本地地址:
? ? ? ? 網絡地址 = IP地址 & 子網掩碼
? ? ? ? ? ? ? ? ? ? ? ? ? 192.168.182.48 & 255.255.255.0 = 192.168.182.0
? ? ? ? 本地地址 = IP地址 & ~子網掩碼
? ? ? ? ? ? ? ? ? ? ? ? ? 192.168.182.48 & 0.0.0.255 = 0.0.0.48
3? 套接字socket
3.0? 理論
????????套接字(socket)本意是電源插座,這里將其引申為一個基于TCP/IP協議可實現基本網絡通信功能的邏輯對象。
? ? ? ? 機器與機器的通信,或者進程與進程的通信,在這里都可以被抽象地看作是套接字與套接字的通信。
? ? ? ? 應用程序編寫者無需了解網絡協議的任何細節,更無需知曉系統內核和網絡設別的運作機制,只要把想發送的數據寫入套接字,或從套接字中讀取想接收的數據即可。
????????
? ? ? ? 從這個意義上講,套接字就相當于一個文件描述符,而網絡就是一種特殊的文件,面向網絡的編程與面向文件的編程已沒有分別,而這恰恰是Unix系統一切皆文件思想的又一例證。?
? ? ? ? 套接字是對ISO/OSI網絡協議模型中傳輸層及其以下諸層的邏輯抽象,是對TCP/IP網絡通信協議的高級封裝,因此無論所依賴的是什么硬件,所運行的什么操作系統,所使用的是什么編程語言,只要是基于套接字構建的應用程序,只要是在互聯網環境中通信,就不會存在任何障礙。
? ? ? ? 如前所述,套接字是一個提供給程序員使用的邏輯對象,它表示對ISO/OSI網絡協議模型中傳輸層及其以下諸層的抽象。但真正發送和接收數據的畢竟是大寫實實在在的物理設備。這就需要在物理設備和邏輯對象之間建立一種關聯,使后續所有針對這個邏輯對象的操作,最終都能夠反映到實際的物理設備上。建立這種關聯關系的過程就叫做綁定:
????????
? ? ? ? 綁定只是把套接字對象和一個代表自己的物理設備關聯起來。為了實現通信還需要把自己的物理設備與對方的物理設備關聯起來。只有這樣才能建立起一種物理設備為媒介的,跨越不同進程甚至機器的,多個套接字對象之間的聯系。建立這種聯系的過程叫做連接:
????????
?3.1? socket()
? ? ? ? #include <sys/socket.h>
? ? ? ? int socket ( int domain,? int type,? int protocol );
? ? ? ? ? ? ? ? 功能:創建套接字
? ? ? ? ? ? ? ? domain:通信域,協議族,可取以下值
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_LOCAL / PF_UNIX? ? ? ? 本地套接字,進程間通信
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_INET? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 基于IPv4的網絡通信
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_INET6? ? ? ? ? ? ? ? ? ? ? ? ? ? 基于IPv6的網絡通信
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PF_PACKET? ? ? ? ? ? ? ? ? ? ? ? 基于底層包的網絡通信?
? ? ? ? ? ? ? ? type:套接字類型,可取以下值
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_STREAM? ? ? ? ? ? ? ? 流式套接字,基于TCP協議
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_DGRAM? ? ? ? ? ? ? ? ? 數據報套接字,基于UDP協議
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_RAW? ? ? ? ? ? ? ? ? ? ? ?原始套接字,工作在傳輸層以下
? ? ? ? ? ? ? ? protocol:特殊協議,對于流式和數據報套接字而言,只能取0
? ? ? ? ????????返回值:成功返回表示套接字對象的文件描述符,失敗返回-1?
? ? ? ? 套接字接口庫通過地址結構定位一個通信主體,可以是一個文件,可以是一臺遠程主機,也可以是執行者自己:
? ? ? ? -基本地址結構,本身沒有實際意義,僅用于泛型化參數
? ? ? ????????????????? struct? sockaddr {
? ? ? ? ? ? ????????????????? ? sa_family_t? ?sa_family;? ????????// 地址族
? ? ? ? ? ? ????????????????? ? char? ? ? ? ? ? ? sa_data[14];? ? ? ?// 地址值
? ? ? ????????????????? };
? ? ? ? -本地地址結構,用于AF_LOCAL/AF_UNIX域的本地通信
? ? ? ?????????????????struct? sockaddr_un {
? ? ? ? ? ? ????????????????? ? sa_family_t? ?sun_family;? // 地址族(AF_LOCAL/AF_UNIX)
? ? ? ? ? ? ????????????????? ? char? ? ? ? ? ? ? sun_path[];? ?// 本地套接字文件的路徑
? ? ? ????????????????? }
? ? ? ? -網絡地址結構,用于AF_INET域的IPv4網絡通信
????????????????????????struct? sockaddr_in {
? ? ? ? ? ? ????????????????? ? sa_family_t? ? ? ? ? sin_family;? // 地址族(AF_INET)
? ? ? ? ? ? ? ? ????????????????in_port_t? ? ? ? ? ? ? sin_port;? ? ?//? 端口號(0~65535) -unsigned short
? ? ? ? ? ? ? ? ????????????????struct? in_addr? ? ?sin_addr;? ? // IP地址 -unsigned int
? ? ? ? ????????????????}????????
? ? ? ? -網絡地址結構,用于AF_INET域的IPv4網絡通信
? ? ? ? ? ? ? ? ? ? ? ? struct? in_addr {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? in_addr_t? s_addr;
? ? ? ? ? ? ? ? ? ? ? ? }
????????????????????????typedef? ?uint16_t? ?in_port_t;? // 無符號16位正數
? ? ? ? ? ? ? ? ? ? ? ? typedef? ?unit32_t? ?in_addr_t; // 無符號32位正數
? ? ? ? 如前所述,通過IP地址可以定位網絡上的一臺主機,但一臺主機上可能同時有多個網絡應用在運行,究竟想跟哪個網絡應用通信呢?這就需要靠端口號來區分,因為不同的網絡應用會使用不同的端口號。用IP地址定位主機,再用端口號定位運行在這臺主機上一個具體的網絡應用,這樣一種對通信主體的描述才是唯一確定的。
? ? ? ? 套接字接口庫中的端口號被定義為一個16位的無符號整數,0~65535,其中0~1024已被系統和一些網絡服務占據:
? ? ? ? 21端口? ? ? ? ftp服務
? ? ? ? 23端口? ? ? ? telnet服務
? ? ? ? 89端口? ? ? ? www服務
? ? ? ? 3306端口? ? 數據庫服務器
? ? ? ? 因此一般程序最好選擇1024以上的端口號,以避免和這些服務沖突。
3.2? bind()
? ? ? ? #include <sys/socket.h>
? ? ? ? int? bind ( int sockfd,? struct sockaddr const* addr,? socklen_t addrlen );
? ? ? ? ? ? ? ? 功能:將套接字和本地的地址結構綁定在一起
? ? ? ? ? ? ? ? sockfd:套接字描述符
? ? ? ? ? ? ? ? addr:自己的地址結構
? ? ? ? ? ? ? ? addrlen:地址結構的字節數
? ? ? ? ? ? ? ? 返回值:成0敗-1?
3.3? connect()
? ? ? ? #include <sys/socket.h>
? ? ? ? int? connect ( int sockfd,? ?struct sockaddr const* addr,? ?socklen_t addrlen );
? ? ? ? ? ? ? ? 功能:將套接字和對方的地址結構連接在一起
? ? ? ? ? ? ? ? sockfd:套接字描述符
? ? ? ? ? ? ? ? addr:對方的地址結構
? ? ? ? ? ? ? ? addrlen:地址結構的字節數
? ? ? ? ? ? ? ? 返回值:成0敗-1?
4? 字節序轉換
? ? ? ? 網絡應用與單擊應用不同,經常需要在具有不同硬件架構和操作系統的計算機之間交換數據,因此編程語言里一些多字節數據類型的字節序問題就特別予以關注。
? ? ? ? 套接字接口庫規定在網絡傳輸過程中采用網絡字節序,也就是大端字節序,而本機數據可能是小端字節序。
? ? ? ? 主機:小端字節序:數據的低位存放在低地址
????????????????
?
? ? ? ? 網絡:大端字節序:數據的低位存放在高地址
????????????????
轉換函數:
? ? ? ? uint32_t? ?htonl ( uint32_t hostlong );? // 長整型? 主機字節序? 到? 網絡字節序
? ? ? ? uint32_t? ?ntohl ( uint32_t netlong );? ? // 長整型? 網絡字節序? 到? 主機字節序
? ? ? ? uint16_t? ?htons ( uint16_t hostshort );? // 短整型? 主機字節序? 到? 網絡字節序
? ? ? ? uint16_t? ?ntohs ( uint16_t netshort?);? ? // 短整型? 網絡字節序? 到? 主機字節序
????????
? ? ? ? in_addr_t? ?inet_addr ( char const* ip ); // 點分十進制字符串地址?到 網絡字節序形式整數地址
? ? ? ? int? ?inet_aton ( char const* ip,? ?struct in_addr* nip );
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 點分十進制字符串地址 到 網絡字節序形式整數地址
? ? ? ? char*? ?inet_ntoa ( struct in_addr nip ); // 網絡字節序形式整數地址 到 點分十進制字符串地址
相關代碼 結合 uc_15