bind
API能够将套接字文件描述符、端口号和ip
绑定到一起
注意:
绑定的一定是自己的 ip和和端口,不是对方的;比如对于TCP服务器来说绑定的就是服务器自己的ip和端口
#include /* See NOTES */#include
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd
表示socket
函数创建的通信文件描述符addrlen
表示所指定的结构体变量的大小addr
表示struct sockaddr
的地址,用于设定要绑定的ip和端口struct sockaddr { sa_family_t sa_family;char sa_data[14];
}
sa_family
用于指定AF_***
表示使用什么协议族的ipsa_data
存放ip和端口struct sockaddr_in
结构体进行写入,通过/usr/include/linux/in.h
可以看到结构体原型
头文件,且sockaddr_in
结构体是专门为tcp/ip协议族使用,其他协议族需要使用其对应的转换结构体,比如“域通信协议族” 使用的是sockaddr_un
结构体struct sockaddr_in { __kernel_sa_family_t sin_family; /* Address family */__be16 sin_port; /* Port number */struct in_addr sin_addr; /* Internet address *//* Pad to size of `struct sockaddr'. 设置IP端口号这个成员暂时用不到 */unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -sizeof(unsigned short int) - sizeof(struct in_addr)];
};/* Internet address.填补相比于struct sockaddr所缺的字节数,保障强制转换不要出错 */
struct in_addr { __be32 s_addr; // __be32是32位的unsigned int ,因为ipv4是无符号32位整型
};
可以看到以上sockaddr_in
结构体中存放的端口和ip是分开的,所以设置起来非常方便,使用struct sockaddr_in
设置后,让后将其强制转换为struct sockaddr
类型,然后传递给bind函数即可struct sockaddr_in addr;
addr.sin_family = AF_INET; //设置tcp协议族
addr.sin_port = htons(6789); //设置端口号
addr.sin_addr.s_addr = inet_addr("192.168.1.105"); //设置ip地址ret = bind(skfd, (struct sockaddr*)&addr, sizeof(addr));
如果是跨局域网或者城域网通信,这里设置的ip地址一定为通信设备所在路由器的外网ip地址。
如下c代码
#include
#include
#include
#include
#include
#include //struct sockadd_in 结构体的头文件
#include
#include
#include void print_err(char *str, int line, int err_no) { printf("%d, %s :%s
",line,str,strerror(err_no));_exit(-1);
}int main()
{ int skfd = -1;skfd = socket(AF_INET, SOCK_STREAM, 0);if ( -1 == skfd) { print_err("socket failed",__LINE__,errno);}struct sockaddr_in addr;addr.sin_family = AF_INET; //设置tcp协议族addr.sin_port = htons(6789); //设置端口号addr.sin_addr.s_addr = inet_addr("192.168.102.169"); //设置ip地址int ret = bind(skfd, (struct sockaddr*)&addr, sizeof(addr));if ( -1 == ret) { print_err("bind failed",__LINE__,errno);}return 0;
}
bind函数就是让套接字文件在通信时使用固定的IP和端口号(针对服务器来说)
可以看到如上实现代码,调用socket函数创建的套接字仅仅执行了通信等协议,但是并没有指定通信时所需的ip地址和端口号
如果不调用bind函数指定ip和端口,则会自己指定一个ip和端口,此时违背了TCP通信的可靠性和面向连接的特点。
可以通过上文TCP通信模型中看到,客户端通信时不需要指定ip和端口号,直接创建一个socket套接字文件描述符即可参与通信。
此时当客户端和服务器建立连接的时候,服务器会从客户的数据包中提取出客户端ip和端口,并保存起来,如果是跨网通信,那么记录的就是客户端所在路由器的公网ip
#include
uint16_t htons(uint16_t hostshort);
函数全拼为host to net shorthtons
兄弟函数htonl
,ntohs
,ntohl
htonl
与htons
唯一的区别时,转换完的端口号为longntohs
与htons
恰好相反,是从网络字节序转换为主机字节序ntohl
表示从网络字节转换为主机序,同时转换完的端口号为long
大端序:
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
小端序:
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
大小端序是由具体的操作系统来决定的
可以使用如下代码测试系统是大端还是小端:
#include
int main()
{ int a = 1;char pc = *(char*)(&a);if (pc == 1)printf("第一个字节为1,小端存储
");elseprintf("第一个字节为0,大端存储
");return 0;
}
同样,网络通信的时候发送端计算机和接收端计算机可能端序不一致,比如发送者是大端序,接受者是小端序,如果通信时数据的端序处理不好很可能出现乱码,甚至无法接收到数据。
如果发送者和接受者端序一致则也能够正常传输数据,不用htons
函数进行转换,不过保证数据序列正确的得进行传输,建议使用htons
函数进行端口号的转换
inet_addr
函数
in_addr_t inet_addr(const char *cp);
草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...
前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...
1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...
原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...
在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...
下面的源码给出了使用boost::asio进行域名解析的方法.
//g++ -g resolver_demo.cpp -o resolver_demo -lboost_system -lpthread
//#include
pc 端配置 点击pc端无线链接图标编辑链接以太网编辑IPv4设置方法:与其他计算机共享根据putty获取的动态ip使用ssh登录 解决 ip 无法登录问题 设置 pc 端 ip 和开发板 ip 在同一个网段 比如开发板 ip 是 10.42.0.123 可以设置自己机器的 ip 为 10.42.0.11 sudo ifcon...
原文:TCP/IP 简介 第一节:TCP/IP 简介 第二节:TCP/IP 寻址 第三节:TCP/IP 协议 第四节:TCP/IP 邮件 TCP/IP 是用于因特网 (Internet) 的通信协议。 计算机通信协议 计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述。 什么是 TC...
#保存一万条命令记录 sed -i 's/^HISTSIZE=1000/HISTSIZE=10000/g' /etc/profile#在/etc/profile的文件尾部添加如下行数配置信息 ######jiagu history xianshi######### USER_IP=`who -u am i 2>/dev/null |...
TCP/IP基础概念及通信过程举例 出现 上个世纪60年代,由于中央集中式网络的容灾性较弱,以美国国防部为中心的一家组织研究出分组交换网络。后来为了验证分组交换技术的实用性,ARPANET出现了,并且在3年内逐渐发展,由4个节点发展至34个节点。20世纪70年代前半叶,ARPANET一个机构研制出了TCP/IP,1982年具体规范...
socket这个词可以表示很多概念: 在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP地址+端口号”就称为socket。 在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接。 socket本身有“插座”...