Socket编程实践(2) --Socket编程导引
什么是Socket?
?? ?Socket可以看成是用戶進程與內核網絡協議棧的接口(編程接口,?如下圖所示),?其不僅可以用于本機進程間通信,可以用于網絡上不同主機的進程間通信,?甚至還可以用于異構系統之間的通信。
?
IPv4套接口地址結構
?? ?IPv4套接口地址結構通常也稱為“網際套接字地址結構”,它以“sockaddr_in”命名,定義在頭文件<netinet/in.h>中
//TCP/IP地址結構 struct sockaddr_in {uint8_t sin_len;sa_family_t sin_family;in_port_t sin_port; //2字節struct in_addr sin_addr; //4字節char sin_zero[8]; //8字節 };成員說明:
?? ?sin_len:整個sockaddr_in結構體的長度,在4.3BSD-Reno版本之前的第一個成員是sin_family.
?? ?sin_family:指定該地址家族,對于IPv4來說必須設為AF_INET
?? ?sin_port:端口
?? ?sin_addr:IPv4的地址;
?? ?sin_zero:暫不使用,一般將其設置為0
?
Linux結構(常用):
struct sockaddr_in {sa_family_t sin_family; /* address family: AF_INET */in_port_t sin_port; /* port in network byte order(網絡字節序) */struct in_addr sin_addr; /* internet address */ }; /* Internet address. */ struct in_addr {uint32_t s_addr; /* address in network byte order */ };通用地址結構
用來指定與套接字關聯的地址(可以支持其他協議).
struct sockaddr {uint8_t sin_len;sa_family_t sin_family;char sa_data[14]; //14字節 };說明:
?? ?sin_len:整個sockaddr結構體的長度
?? ?sin_family:指定該地址家族
?? ?sa_data:由sin_family決定它的形式。
?
網絡字節序
1.大端字節序(Big?Endian)
?? ?最高有效位(MSB:Most?Significant?Bit)存儲于最低內存地址處,最低有效位(LSB:Lowest?Significant?Bit)存儲于最高內存地址處。
2.小端字節序(Little?Endian)
?? ?最高有效位(MSB:Most?Significant?Bit)存儲于最高內存地址處,最低有效位(LSB:Lowest?Significant?Bit)存儲于最低內存地址處。
3.主機字節序
?? ?不同的主機有不同的字節序,如x86為小端字節序,Motorola?6800為大端字節序,ARM字節序是可配置的。
4.網絡字節序
?? ?網絡字節序規定為大端字節序
//測試當前系統是否為小端模式 int main() {int data = 0x12345678; //int = 4字節(32位)//每4個二進制位代表1位十六進制位,//則8位十六進制位代表4*8=32位二進制位char *p = (char *)&data;printf("%x, %x, %x, %x\n",p[0],p[1],p[2],p[3]);//0x78屬于低位,如果其放在了p[0](低地址)處,則說明是小端模式if (p[0] == 0x78){cout << "當前系統為小端模式" << endl; //x86平臺為小端模式}else if (p[0] == 0x12){cout << "當前系統為大端模式" << endl; //IBM為大端模式} }字節序轉換函數(常用于端口轉換)
uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); /**說明: h代表(local)host;n代表network; s代表short;l代表long; */ //測試轉換結果 int main() {int localeData = 0x12345678;char *p = (char *)&localeData;printf("Begin: %0x %0x %0x %0x\n", p[0], p[1], p[2], p[3]);//將本地字節轉換成網絡字節int inetData = htonl(localeData);p = (char *)&inetData;printf("After: %0x %0x %0x %0x\n", p[0], p[1], p[2], p[3]);if (p[0] == 0x12)cout << "網絡系統為大端模式" << endl;elsecout << "網絡系統為小端模式" << endl;printf("host:%x, inet:%x\n", localeData, inetData); }地址轉換函數(用于IP地址轉換)
#include <netinet/in.h> #include <arpa/inet.h> int inet_aton(const char *cp, struct in_addr *inp); in_addr_t inet_addr(const char *cp); char *inet_ntoa(struct in_addr in); //in_addr定義如下: typedef uint32_t in_addr_t; struct in_addr {in_addr_t s_addr; };套接字類型
1)流式套接字(SOCK_STREAM)
?? ?提供面向連接的、可靠的數據傳輸服務,數據無差錯,無重復的發送,且按發送順序接收,?對應TCP協議。
2)數據報式套接字(SOCK_DGRAM)
?? ?提供無連接服務。不提供無錯保證,數據可能丟失或重復,并且接收順序混亂,?對應UDP協議。
3)原始套接字(SOCK_RAW)
?? ?使我們可以跨越傳輸層直接對IP層進行封裝傳輸.
?
TCP客戶/服務器模型?
簡單echo服務器模型
?
總結
以上是生活随笔為你收集整理的Socket编程实践(2) --Socket编程导引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Bugzilla安装过程
- 下一篇: web.py开发web 第四章 Sqla