在上篇文章中我们提到了UDP,TCP有关函数,并知道了一个重要的结构体struct sockaddr。想要实现通信首先要知道通信端的地址,所以首先了解一下IPv4套接字地址结构体。
struct sockaddr_in
{
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8]
};
struct in_addr
{
in_addr_t s_addr;
};
注意 : 为了使不同格式地址能被传入套接字函数,地址须要强制转换成通用套接字地址结构。
struct sockaddr
{
sa_family_t sa_family;
char sa_data[14];
};
所以现在就是怎样给IPv4结构体赋值的问题了。
例子 :
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
inet_pton(AF_INET,"10.0.110.110",&server_addr.sin_addr.s_addr)
接下来了解网络编程中的字节序(大小端)、字节序转换函数和地址转换函数。
1.字节序
概念:多字节数据的存储顺序
分类:
(1)大端格式:将高位字节数据存储在低位地址上
(2)小端格式:将低位字节数据存储在低位地址上
特点
1、网络协议指定了通讯字节序——大端
2、只有在多字节数据处理时才需要考虑字节序
3、运行在同一台计算机上的进程相互通信时,一般不用考虑字节序
4、异构计算机之间通讯,需要转换自己的字节序为网络字节序
确定主机的字节序程序。(了解)
#include <stdio.h>
union{
short s;
char c[sizeof(short)];
}un;
int main(int argc, const char *argv[])
{
un.s =0x0102;
if((un.c[0]==1)&&(un.c[1]==2))
printf("big-endian\n");
if((un.c[0]==2)&&(un.c[1]==1))
printf("little-endian\n");
return 0;
}
2.字节序转换函数
注意 : 在需要字节序转换的时候一般调用特定字节序转换函数。
(1)htonl 函数
uint32_t htonl(uint32_t hostint32);
功能:将32位主机字节序数据转换成网络字节序数据
参数:
@hostint32 : 待转换的 32 位主机字节序数据
返回值:
成功:返回网络字节序的值 失败:一般不失败
注意:
将主机字节序的IP地址转换成网络字节序的IP地址。(重点)
头文件:
#include <arpa/inet.h>
(2)htons 函数
uint16_t htons(uint16_t hostint16);
功能:将16位主机字节序数据转换成网络字节序数据
参数:
@hostint16 : 待转换的 16 位主机字节序数据
返回值:
成功:返回网络字节序的值 失败:一般不失败
注意:
将主机字节序的port端口号转换成网络字节序的port端口号(重点)
头文件:
#include <arpa/inet.h>
在上面给IPv4结构体变量赋值是用到的htons函数,应该就容易理解了。
(3)ntohl 函数
uint32_t ntohl(uint32_t netint32);
功能:将32位网络字节序数据转换成主机字节序数据
参数:
@netint32 : 待转换的32位网络字节序数据
返回值:
成功:返回主机字节序的值
注意:
将网络字节序的IP地址转换成主机字节序的IP(一般在对接收的数据分析时用来查看ip)
头文件:
#include <arpa/inet.h>
(4)ntohs 函数
uint16_t ntohs(uint16_t netint16);
功能:将16位网络字节序数据转换成主机字节序数据
参数:
@netint16 : 待转换的16位网络字节序数据
返回值:
成功:返回主机字节序的值
注意:
将网络字节序的port端口号转换成主机字节序的port端口号(一般在对接收的数据分析时用来查看ip)
头文件:
#include <arpa/inet.h>
3.地址转换函数
在网络通信中IP地址是32位,实际中是点分十进制数串(10.0.110.110直观)。
(1)inet_pton 函数
字符串ip地址转整型数据 (点分十进制数串 转 32位网络字节序IP)
int inet_pton(int family,const char *strptr, void *addrptr);
功能:将点分十进制数串转换成32位无符号整数
参数:
@family : 协议族
@strptr : 点分十进制数串(例:10.0.110.110)
@addrptr : 32位无符号整数的地址
返回值:
成功:返回1 失败:其它
头文件:
#include <arpa/inet.h>
在上面给IPv4结构体变量赋值是用到的inet_pton函数,应该就容易理解了。
(2)inet_ntop 函数
整型数据转字符串格式ip地址 (32位网络字节序IP 转 点分十进制数串)
char *inet_ntop(int family, const void *addrptr,char *strptr, size_t len);
功能:将32位无符号整数转换成点分十进制数串
参数:
family : 协议族
addrptr : 32位无符号整数
strptr : 点分十进制数串
len : strptr缓存区长度
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
返回值:
成功:则返回字符串的首地址 失败:NULL
头文件:
#include <arpa/inet.h>
到这,可以说从TCP三次握手四次握手 、 TCP,UDP有关函数 到 网络通信有关函数已经通了。可以自己写个有关TCP或UDP通信程序了。
朋友,加油!点个关注…
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)