socket编程--socket基本概念
2015-08-08 15:49
246 查看
socket
socket可以看成是用户进程与内核网络协议栈的编程接口,不仅可以用于本机的进程间通信,也可以用于网络上不同主机的进程间通信—而管道只能在同一台主机进行通信
应用层依靠socket进行数据传输,我们不必关心底层的内核,即底层数据的传输细节,只关心套接口的存在。
可以把套接口看成进程间的通信,主机A上的进程通过套接口传输数据到主机B的进程。
说明:sin_len:整个sockaddr_in结构体的长度
sin_family:指定该地址家族,在这里必须设为AF_INET – IPv4
sin_port:端口
sin_addr:IPv4地址
sin_zero:暂不使用,一般将其设为0
其中,结构体in_addr:
结构体in_addr用来表示一个32位的IPv4地址–字节序为网络字节序
通用地址结构
通用地址结构用来指定与套接字关联的地址
说明:sin_len:整个sockaddr结构体的长度
sin_family:指定该地址家族
sa_data:由sin_family决定它的形式
可看到:通用地址结构中的da_data有14个字节和IPv4 sin_port(2字节)、sin_addr(4字节)、sin_zero(8字节)相同,说明这两个兼容,通常,进行TCP/IP编程时跟多的是填充IPv4套接口地址结构,然后强制转换为通用地址结构。
1、大端字节序(Big EndIan)
最高有效位存储在最低内存地址处,最低有效位存储在最高内存地址处
2、小端字节序(Little EndIan)
最高有效位存储在最高内存地址处,最低有效位存储在最低内存地址处
主机主机序
不同主机有不同的字节序,如x86位小端字节序,Motorola 6900为大端字节序,ARM字节序为可配置的
网络字节序
网络字节序规定为大端字节序
为什么要引入字节序这个概念?
socket能够实现异构系统间通信,不同系统字节序不同,引入字节序可实现异构系统通信
测试主机大小端:
int main()
{
unsigned int x = 0x12345678;
unsigned char p = (unsigned char )&x;
printf(“%0x %0x %0x %0x”, p[0],p[1],p[2],p[3]);
return 0;
}
高地址存高内存地址—小端字节序
字节序转换函数
uint32_t htonl(uint32_t hostlong); //将4个字节的主机字节序转换为网络字节序
uint32_t htons(uint32_t hostshort);//2个字节的主机字节序转换为网络字节序
uint32_t ntohl(uint32_t netlong); //相反
uint32_t ntohs(uint32_t netshort);
说明:h代表host;n代表network
s代表short;l代表long
主机字节序转换为了网络字节序(大端字节序)
inet_addr将一个点分十进制IP地址字符串转换成32位数字表示的IP地址(网络字节顺序)。
char* inet_ntoa (struct in_addr in);
inet_ntoa将一个32位数字表示的IP地址转换成点分十进制IP地址字符串。
这两个函数互为反函数
unsigned char *ip = “192.168.1.120”;
int int_ip = inet_addr(ip);
printf(“%d\n”, int_ip);
提供面向连接、可靠的数据传输服务,数据按字节流、按顺序收发,保证在传输过程中无丢失、无冗余。TCP协议支持该套接字。
(2)数据报套接字 SOCK_DGRAM – UDP
提供面向无连接的服务,数据收发无序,不能保证数据的准确到达。UDP协议支持该套接字。
(3)原始套接字 SOCK_RAW
允许对低于传输层的协议或物理网络直接访问,例如可以接收和发送ICMP报文。常用于检测新的协议。
socket可以看成是用户进程与内核网络协议栈的编程接口,不仅可以用于本机的进程间通信,也可以用于网络上不同主机的进程间通信—而管道只能在同一台主机进行通信
应用层依靠socket进行数据传输,我们不必关心底层的内核,即底层数据的传输细节,只关心套接口的存在。
可以把套接口看成进程间的通信,主机A上的进程通过套接口传输数据到主机B的进程。
IPv4套接字地址结构
struct sockaddr_in{ uint8_t sin_len; /*length of the structure*/ sa_family_t sin_family; /*AF_INET*/ in_port_t sin_port; /*16bits TCP or UDP port number*/ struct in_addr sin_addr; char sin_zeor[8]; /*unused*/ };
说明:sin_len:整个sockaddr_in结构体的长度
sin_family:指定该地址家族,在这里必须设为AF_INET – IPv4
sin_port:端口
sin_addr:IPv4地址
sin_zero:暂不使用,一般将其设为0
其中,结构体in_addr:
struct in_addr { in_addr_t s_addr; };
结构体in_addr用来表示一个32位的IPv4地址–字节序为网络字节序
通用地址结构
通用地址结构用来指定与套接字关联的地址
struct sockaddr{ uint8_t sin_len; sa_family_t sin_family; /*AF_INET*/ char da_data[14]; };
说明:sin_len:整个sockaddr结构体的长度
sin_family:指定该地址家族
sa_data:由sin_family决定它的形式
可看到:通用地址结构中的da_data有14个字节和IPv4 sin_port(2字节)、sin_addr(4字节)、sin_zero(8字节)相同,说明这两个兼容,通常,进行TCP/IP编程时跟多的是填充IPv4套接口地址结构,然后强制转换为通用地址结构。
网络字节序
字节序1、大端字节序(Big EndIan)
最高有效位存储在最低内存地址处,最低有效位存储在最高内存地址处
2、小端字节序(Little EndIan)
最高有效位存储在最高内存地址处,最低有效位存储在最低内存地址处
主机主机序
不同主机有不同的字节序,如x86位小端字节序,Motorola 6900为大端字节序,ARM字节序为可配置的
网络字节序
网络字节序规定为大端字节序
为什么要引入字节序这个概念?
socket能够实现异构系统间通信,不同系统字节序不同,引入字节序可实现异构系统通信
测试主机大小端:
int main()
{
unsigned int x = 0x12345678;
unsigned char p = (unsigned char )&x;
printf(“%0x %0x %0x %0x”, p[0],p[1],p[2],p[3]);
return 0;
}
高地址存高内存地址—小端字节序
字节序转换函数
uint32_t htonl(uint32_t hostlong); //将4个字节的主机字节序转换为网络字节序
uint32_t htons(uint32_t hostshort);//2个字节的主机字节序转换为网络字节序
uint32_t ntohl(uint32_t netlong); //相反
uint32_t ntohs(uint32_t netshort);
说明:h代表host;n代表network
s代表short;l代表long
int main() { unsigned int x = 0x12345678; unsigned char *p = (unsigned char *)&x; printf("%0x %0x %0x %0x\n", p[0],p[1],p[2],p[3]); unsigned int y = htonl(x); p = (unsigned char*)&y; printf("%0x %0x %0x %0x\n", p[0], p[1], p[2], p[3]); return 0; }
主机字节序转换为了网络字节序(大端字节序)
地址转换函数
in_addr_t inet_addr (const char *cp);inet_addr将一个点分十进制IP地址字符串转换成32位数字表示的IP地址(网络字节顺序)。
char* inet_ntoa (struct in_addr in);
inet_ntoa将一个32位数字表示的IP地址转换成点分十进制IP地址字符串。
这两个函数互为反函数
unsigned char *ip = “192.168.1.120”;
int int_ip = inet_addr(ip);
printf(“%d\n”, int_ip);
struct in_addr ipaddr ; ipaddr.s_addr = int_ip; printf("%s\n", inet_ntoa(ipaddr));
套接字类型
(1)流式套接字 SOCK_STREAM — TCP提供面向连接、可靠的数据传输服务,数据按字节流、按顺序收发,保证在传输过程中无丢失、无冗余。TCP协议支持该套接字。
(2)数据报套接字 SOCK_DGRAM – UDP
提供面向无连接的服务,数据收发无序,不能保证数据的准确到达。UDP协议支持该套接字。
(3)原始套接字 SOCK_RAW
允许对低于传输层的协议或物理网络直接访问,例如可以接收和发送ICMP报文。常用于检测新的协议。
相关文章推荐
- Struts2 入门教程
- springmvc的数据校验
- Going Home - poj 2195(最小费用流 | 二分匹配)
- java运行内存结构
- Java--引用与指针
- Calendar日历类,Date类
- C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)
- 【C语言】冒泡排序与回文判断
- java里的分支语句--程序运行流程的分类(顺序结构,分支结构,循环结构)
- 什么是Java集合API?
- java之进程理解
- 【C语言】在终端输入多行信息,找出包含“ould”的行,并打印改行。
- Java程序运行机制及运行过程
- 机房收费系统颗粒大归仓之----DTPicker控件与导出数据为Excel
- C++使用CInternetSession请求url下载jason数据,并且进行解析。以及注意事项
- 【C语言】学生成绩链表的录入
- github的使用方法
- windows下向GitHub上传代码
- 深入浅出Java回调机制
- ubuntu下Python虚拟环境的安装、激活、退出