前一篇关于windows平台下winsock套接字编程的相关api
struct sockaddr与struct sockaddr_in
在bind函数,connect函数里提到了套接字编程网络地址信息结构体const struct sockaddr和const struct sockaddr_in
关于const struct sockaddr是通用的套接字网络地址信息结构体,而const struct sockaddr_in主要针对于TCP/IP协议体系的网络地址信息存储(sockaddr_in更适合操作)
二者的内存占用一样,所以在调用对应api时候,可以直接将sockaddr_in进行类型强转为sockaddr即可
看一下二者的内部结构
struct sockaddr
{
unsigned short int sa_family; //协议族
unsigned char sa_data[14]; //地址信息
}
struct sockaddr_in
{
short sin_family; //协议族
unsigned short int  sin_port; //端口号(windows平台部分编译环境下,可能将此类型typdef为in_port_t)
struct in_addr sin_addr; //intenet地址信息,详细内容之后讨论
unsigned char sin_zero[len]; //充填部分
}
我们着重看一下struct sockaddr_in这个结构体
  • short sin_family,对于TCP/IP协议,赋值AF_INET即可
  • unsigned short int sin_port,通信的端口号(网络字节序赋值,关于主机字节序和网络字节序的区别,之后讨论),我在vs2015下,unsigned short int类型被typedef为in_port_t。
  • struct in_addr sin_addr,保存internet地址信息,也就是我们常说的IP地址,这是一个结构体,来看一下它的内容
struct in_addr
{
union
{
struct 
{
uchar s_b,s_b2,s_b3,s_b4;
}S_un_b;
struct
{
ushort s_w1,s_w2;
}S_un_w;
u_long S_addr; //网络字节序
}S_un;
}    
struct in_addr结构体中,使用联合union,三种方式来保存IP地址信息;
关于IP地址,这是一个4字节的无符号整型,此结构体也就对应了三种保存方式:1.S_un_b单字节保存为;2.S_un_w,双字节保存;3.S_addr,4字节保存;
我们常用S_addr4字节直接保存IP地址信息
  • unsigned char sin_zero[len]用来充填对齐,使sockaddr_in与sockaddr内存对齐,不用关注。
网络字节序与主机字节序
在之前,一直提到对应的端口port与网络地址IP地址,必须使用网络字节序来操作。
什么是网络字节序,还有对应的主机字节序是什么?
首先,我们先看一下目前计算机当中存在的两种字节序
little_endian,big_endian
对于一个数,在计算机内存存储有两种方式:
一,将数字的低位存在内存的起始地址上,称为little_endian
二,将数字的高位存在内存的起始地址上,称为big_endian
由于目前计算机工艺的区别,不同计算机采用了不同的存储序,我们可以通过一些方式查询到自己计算机的字节序(本文不再赘述,可自行查找)
为了保证计算机在网络通信时,不会因为两种顺序造成寻址失败,规定将 big_endian称为网络字节序
PS:主机字节序与little_endian、big_endian没有直接关系。并不是说little_endian就是主机字节序。主机字节序是根据本台计算机的硬件决定的,主机字节序既可能是little_endian,也可能是big_endian。
所以,我们在操作sockaddr_in里sin_port和sin_addr时,一定要将网络字节序的端口号和IP地址操作进去
(关于网络字节序与主机字节序的转换函数,之后介绍)
举例:
对于点分十进制IP地址“192.168.3.31”,这是一个4字节的数据
对应的二进制:1100 0000     1010 1000     0000 0011     0001 1111
对应十进制  ‭3232236319‬
如果转换到网络字节序(big_endian)下,那么高位就会存放在起始位置上(4字节数据颠倒存放)
那么对应的二进制:0001 1111     0000 0011     1010 1000     1100 0000
对应十进制: ‭520333504‬
转换函数:(h-host主机,n-net网络,l-long4字节,s-short2字节)
主机字节序转换为网络字节序:
u_long htonl(u_long hostlong); //4字节
u_short htons(u_short hostshort);  //2字节
网络字节序转换为主机字节序:
u_long ntohl(u_long netlong); //4字节
u_long ntohs(u_short netshort); //2字节
对于sockaddr,sockaddr_in结构体中的 端口号sin_port,需要使用2字节的转换函数来转换
对于in_addr结构体中的S_addr,需要使用4字节转换函数来转换
另一种IP地址的转换函数:
    对于上面提到的转换函数,使用起来必然是很困难的,因为我们日常中常见的IP地址是点分十进制“192.168.1.1”这样的形式。
    如果我们需要使用上面的函数,则需要自己先手工将点分十进制转换成普通十进制二进制才能使用。这样很麻烦。
    所以,我们有其他直接将点分十进制char类型转换成网络字节序的函数
    unsigned long inet_addr inet_addr(const char *cp);
    我们可以直接将const char *cp="192.168.1.1"这样形式的IP地址使用该函数转换为网络字节序。
    
    但是,我使用的是windows10,VS2015环境,如果使用这个函数,则会编译报错。
    会提示使用inet_pton()函数来进行转换
    查了相关资料,inet_addr函数相对较旧,不支持IPv6,所以VS2015已经不支持,VS2010目测支持。而linux平台下,win平台下使用codeblock附加对应库函数,也可以使用。
    但是为了保证VS2015的正常运行,所以我还是改用了支持IPv6的inet_pton()函数。
    
    函数int inet_pton(int af, const char *src, void *dst); 附加头函数#include<WS2tcpip.h>
    参数:af-协议地址族 TCP/IP协议使用AF_INET
               src-字符串形式的点分十进制IP地址
               对应的in_addr结构体指针,必须使用void类型强转

【C++】Winsock套接字编程,struct sockaddr、sockaddr_in,主机网络字节序相关推荐

  1. 套接字编程--1(UDP协议编程,端口号,传输层协议,网络字节序)

    传输层的协议: ip地址: 在网络中唯一标识一台主机 IPV4:uint32_t DHCP NAT IPV6 : uint8_t addr[16] -向前并不兼容IPV4 每一条数据都必须包含源地址和 ...

  2. socket网络套接字编程

    目录 UDP通信程序的编写: udp通信流程*: 接口认识: 字节序转换接口*: 查看网络连接状态的命令: 实现构建思路: udp_srv.c: udp_socket.hpp: udp_client. ...

  3. Linux 网络编程详解一(IP套接字结构体、网络字节序,地址转换函数)

    IPv4套接字地址结构 struct sockaddr_in {uint8_t sinlen;(4个字节)sa_family_t sin_family;(4个字节)in_port_t sin_port ...

  4. Linux_c++ TCP套接字编程函数

    socket函数 int socket(int domain,int type,int protocol); domain为协议簇,取值为以下几点 AF_INET:使用Ipv4协议 AF_INET6: ...

  5. 计算机网络详解--套接字编程

    目录 1.什么是网络编程 2.TCP/IP协议 3.Socket套接字 流套接字:使用传输层TCP(传输控制协议) 数据报套接字:使用传输层UDP(用户数据报协议) 原始套接字 4.Java数据报套接 ...

  6. Python中的套接字编程

    文章目录 **连接到服务器:** **一个简单的服务器客户端程序:** **服务器** **客户端** 套接字编程是一种连接网络上的两个节点以相互通信的方法.一个套接字(节点)侦听 IP 处的特定端口 ...

  7. 套接字编程(VC_Win32)

    简介(源于维基) Berkeley套接字(也作BSD套接字应用程序接口)刚开始是4.2BSD Unix操作系统(于1983发布)的一套应用程序接口.然而,由于AT&T的专利保护着UNIX,所以 ...

  8. 《c语言从入门到精通》看书笔记——第16章 网络套接字编程(下)——套接字

    1.套接字概述 套接字是网络通信的基石,是网络通信的基本构件. 所谓套接字,实际上是一个指向传输提供者的句柄.在WinSock中,就是通过操作该句柄来实现网络通信和管理的.根据性质和作用不同,套接字可 ...

  9. 孙鑫MFC笔记之十四--多线程同步与异步套接字编程

    线程同步有三种方式: 1.      互斥对象涉及方法: HANDLE hMutex=CreateMutex(NULL,FALSE,NULL); //第二个参数为FALSE,将互斥对象声明为空闲状态 ...

最新文章

  1. Windows 下noinstall方式安装 mysql-5.7.5-m15-winx64
  2. android远程控制灯光,智能灯具如何实现远程控制技术
  3. 如何设计第三方账号登陆?
  4. 【Solr专题之九】SolrJ教程
  5. 建立主键应该遵循的原则
  6. 宁波python学习_python学习第五天
  7. 【电子签章】HTML格式合同转化成PDF文件 已下载
  8. mysql 停数据库_mysql数据库突然停了
  9. Linux系统调用表(x86_64)
  10. mysql 4604,mysql--centos(7)安装
  11. linux ping 命令_Linux ping命令示例
  12. Centos7.4 安装Docker CE版
  13. 210920-车站问题
  14. Pytorch优化器全总结(二)Adadelta、RMSprop、Adam、Adamax、AdamW、NAdam、SparseAdam
  15. win7文件夹加密软件_winRAR去广告版软件安装教程
  16. java写一个音乐播放程序,同时显示歌词
  17. 前端和后端的英文_前端开发与架构师
  18. STM32H743 USART1 LL 库
  19. 微信小程序检测版本是否有更新
  20. 从IP138上获取数据,查询多个IP的归宿地

热门文章

  1. android 界面分栏,华为Mate10怎么分屏?华为Mate10/10 Pro分栏分屏模式开启教程
  2. Java左刀右叉问题
  3. amd插帧技术如何开启_让游戏帧数暴涨,RX 590解锁蓝宝独家黑科技
  4. 用手机拍摄视频技巧大全
  5. hive求解身份证号的正确性
  6. 第2章 C语言的常量 (五)
  7. 【米家】Charles 抓包调试
  8. Android指定专用APN
  9. Delphi实现sql 复制编程
  10. Java,你告诉我 fail-fast 是什么鬼?