Socket编程 - 网络基础知识
生活随笔
收集整理的這篇文章主要介紹了
Socket编程 - 网络基础知识
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
API編程部分:http://www.cnblogs.com/Jimmy1988/p/7895213.html
1. 協議簡介
此處,我們主要介紹Linux編程常用的三種協議(TCP/UDP/IP), 關于三種協議的定義,可參見各自的頭文件:
- /usr/include/linux/tcp.h
- /usr/include/linux/udp.h
- /usr/include/linux/ip.h
①. TCP
/** Come from /usr/include/linux/tcp*/ struct tcphdr {__be16 source;__be16 dest;__be32 seq;__be32 ack_seq; #if defined(__LITTLE_ENDIAN_BITFIELD)__u16 res1:4,doff:4,fin:1,syn:1,rst:1,psh:1,ack:1,urg:1,ece:1,cwr:1; #elif defined(__BIG_ENDIAN_BITFIELD)__u16 doff:4,res1:4,cwr:1,ece:1,urg:1,ack:1,psh:1,rst:1,syn:1,fin:1; #else #error "Adjust your <asm/byteorder.h> defines" #endif__be16 window;__sum16 check;__be16 urg_ptr; };| 源端口 | 16 | 源端口和IP地址的作用是標識報文的返回地址 |
| 目的端口 | 16 | 端口指明接收方計算機上的應用程序接口 常用端口: ?- ftp/tftp:?; 20、21/69 ?- SSH: ?22 ?- telent:?23 ?- smtp: ?25 ?- http/https: ?80/443 ?- pop3/snmp: ?110/163 (詳細信息參見:http://cert.sjtu.edu.cn/doc/linux/ch-ports.html) 或者參見Linux的文件 /usr/services |
| 序號 | 32 | 本報文段發送的數據組的第一個字節的序號 |
| 確認序號 | 32 | 下一個期待收到的字節序號 |
| 數據偏移/首部長度 | 4 | TCP報頭的長度 報頭長度=首部長度*32bit |
| 保留 | 4 | 為將來定義新的用途保留,現在一般置0 |
| URG | 1 | 緊急指針標志 - 為1時表示緊急指針有效 - 為0則忽略緊急指針 |
| ACK | 1 | 確認序號標志 - 為1時表示確認號有效 - 為0表示忽略確認號字段 |
| PSH | 1 | push標志 - 1:指示接收方在接收到該報文段以后, ??應盡快將這個報文段交給應用程序,而不是在緩沖區排隊 |
| RST | 1 | 重置連接標志 用于重置由于主機崩潰或其他原因而出現錯誤的連接。 或者用于拒絕非法的報文段和拒絕連接請求 |
| SYN | 1 | 同步序號 用于建立連接過程,在連接請求中, - SYN=1和ACK=0表示該數據段沒有使用捎帶的確認域; - SYN=1和ACK=1,而連接應答捎帶一個確認 |
| FIN | 1 | finish標志,用于釋放連接 - 1: 表示發送方已經沒有數據發送了,即關閉本方數據流 |
| 窗口 | 16 | 滑動窗口大小 用來告知發送端接受端的緩存大小, 以此控制發送端發送數據的速率, 從而達到流量控制 |
| 校驗和 | 16 | 奇偶校驗 此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 數據,以 16 位字進行計算所得; 由發送端計算和存儲,并由接收端進行驗證。 |
| 緊急指針 | 16 | 只有當 URG 標志置 1 時緊急指針才有效 緊急指針是一個正的偏移量,和順序號字段中的值相加 表示緊急數據最后一個字節的序號。 |
| 選項和填充 | 32 | 表示本端所能接受的最大報文段的長度 |
②. UDP
/** Come from /usr/include/linux/udp.h*/ struct udphdr {__be16 source;__be16 dest;__be16 len;__sum16 check; };| 源端口 | 16 | 源端口號。在需要對方回信時選用。不需要時可用全0 |
| 目的端口 | 16 | 目的端口號。這在終點交付報文時必須要使用到 |
| 長度 | 16 | UDP用戶數據報的長度,其最小值是8(僅有首部) |
| 校驗和 | 16 | 檢測UDP用戶數據報在傳輸中是否有錯。有錯就丟棄 |
③. IP
/* * Comes from /usr/include/linux/ip.h*/struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD)__u8 ihl:4,version:4; #elif defined (__BIG_ENDIAN_BITFIELD)__u8 version:4,ihl:4; #else #error "Please fix <asm/byteorder.h>" #endif__u8 tos;__be16 tot_len;__be16 id;__be16 frag_off;__u8 ttl;__u8 protocol;__sum16 check;__be32 saddr;__be32 daddr;/*The options start here. */ };| version | 4 | IP協議的版本 |
| IHL (Internet Header Length) | 4 | IP報頭的長度 固定部分的長度(20字節)和可變部分的長度之和 **Length=IHL*32bit** |
| TOS (Type Of Service) | 8 | IP數據包的服務類型 |
| 總長度 | 16 | IP報文的總長度 報頭的長度和數據部分的長度之和 |
| 標識 | 16 | 唯一的標識主機發送的每一分數據報 通常每發送一個報文,它的值加一。 當IP報文長度超過傳輸網絡的MTU(最大傳輸單元)時必須分片, 這個標識字段的值被復制到所有數據分片的標識字段中, 使得這些分片在達到最終目的地時 可以依照標識字段的內容重新組成原先的數據。 |
| 標志 | 3 | R、DF、MF三位 目前只有后兩位有效 - DF位:為1表示不分片,為0表示分片; - MF:為1表示“更多的片”,為0表示這是最后一片 |
| 片位移 | 13 | 本分片在原先數據報文中相對首位的偏移位 (需要再乘以8) |
| TTL (Time To Live) | 8 | IP報文所允許通過的路由器的最大數量 每經過一個路由器,TTL減1; 當為0時,路由器將該數據報丟棄 |
| 協議 | 8 | 指出IP報文攜帶的數據使用的是那種協議, 以便目的主機的IP層能知道要將數據報上交到哪個進程。 - TCP: 6 - UDP: 17 - ICMP: 1 - IGMP: 2 |
| 首部校驗和 | 16 | 計算IP頭部的校驗和, 檢查IP報頭的完整性 |
| 源IP地址 | 32 | 標識IP數據報的源端設備 |
| 目的IP地址 | 32 | 標識IP數據報的目的地址。 |
2. IPv4相關操作
/* Internet address. */ typedef uint32_t in_addr_t; struct in_addr {in_addr_t s_addr; };①. IPv4地址轉換
| in_addr_t inet_addr( const char *cp) | cp:十進制字符串 | 成功:0 失敗:非0 | 將點分十進制字符串 轉換為32位網絡字節(大端) |
| in_addr_t inet_network( const char *cp) | cp:十進制字符串 | 成功:32bit 地址 失敗:非0 | 將點分十進制字符串 轉換為32位主機字節順序的IP地址 |
| char *inet_ntoa( struct in_addr in) | in:32bit網絡IP | 點分十進制字符串 | 將32bit的網絡順序字節 轉化為點分十進制字符串方式 |
| int inet_aton( const char *cp, struct in_addr *inp | 1.cp: 欲轉化的點分十進制IP的首地址 2.inp:轉化結果的地址空間首地址 | 成功:0 失敗:非0 | 點分十進制字符串 轉化為32bit的網絡順序字節順序 |
②. 獲取ID
| in_addr_t inet_lnaof( struct in_addr in) | in:ip地址 | 返回標準主機ID | 獲取標準主機ID |
| in_addr_t inet_netof( struct in_addr in) | in:ip地址 | 返回標準主機ID | 獲取標準網絡ID |
| struct in_addr inet_makeaddr( int net, int host) | 1.net:網絡ID 2.host:主機ID | 返回IP | 將主機ID和網絡ID合成標準IP |
3. 大端小端
- 大端:Big-Endian
即內存高地址存放數據的低字節:如0x1234,存放在0x4000~0x4001,則0x4000存0x12,0x4001存0x34
網絡字節順序統一采用大端 - 小端:Little-Endian
與大端相反,即高地址存放高字節
x86系列處理器為小端模式
①.程序判斷大小端
#include <stdio.h>int main() {union end_un{unsigned short int word;char ch;}endian;endian.word = 0x1234;if(endian.ch == 0x12){printf("This is Big-Endian!\n");}else if(endian.ch == 0x34){printf("This is Little-Endian!\n");}return 0; }②. 字節順序轉化函數
頭文件:#include <arpa/inet.h>
| uint32_t htonl(uint32_t hostlong) | long host to net |
| uint16_t htons(uint16_t hostshort) | short host to net |
| uint32_t ntohl(uint32_t netlong ) | long net to host |
| uint16_t ntohs(uint16_t netshort ) | short net to host |
轉載于:https://www.cnblogs.com/Jimmy1988/p/7839940.html
總結
以上是生活随笔為你收集整理的Socket编程 - 网络基础知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Deconvolution与Upsamp
- 下一篇: NET全控件