网站网页框架构架图怎么做,百度下拉框推广网站,长春火车站到吉大二院,网站源码建站视频教程知识了解#xff1a;
1.IP:本质是一个整型数#xff0c;用于表示计算机在网络中的地址。IP协议版本有两个#xff1a;IPv4和IPv6
IPv4#xff08;Internet Protocol version4#xff09;: 使用一个32位的整型数描述一个IP地址#xff0c;4个字节#xff0c;int型也可以…知识了解
1.IP:本质是一个整型数用于表示计算机在网络中的地址。IP协议版本有两个IPv4和IPv6
IPv4Internet Protocol version4: 使用一个32位的整型数描述一个IP地址4个字节int型也可以使用一个点分十进制字符串描述这个IP地址: 192.168.247.135分成了4份每份1字节8bit(char)最大值为255 0.0.0.0 是最小的IP地址255.255.255.255是最大的IP地址按照IPv4协议计算可以使用的IP地址共有2^32个 IPv6Internet Protocol version6: 使用一个128位的整型数描述一个IP地址16个字节也可以使用一个字符串描述这个IP地址: 2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b分成了8份每份2字节每一部分以16进制的方式表示按照IPv6协议计算可以使用的IP地址共有2^18个数 2.端口
端口的作用是定位到主机上的某一个进程通过这个端口进程就可以接收到对应的数据了。
比如在电脑上运行了微信和QQ小明通过客户端给我的微信发消息电脑上的微信就收到了消息为什么 运行在电脑上的微信和QQ都绑定了不同的端口通过IP地址可以定位到某一台主机通过端口就可以定位到主机上的某一个进程通过指定的IP和端口发送数据的时候对端就能接收到数据了 端口也是一个整形数unsigned short一个16位整型数有效端口的取值范围是:0~65535(0~2^16-1)
提问计算机中所有的进程都需要关联一个端口吗一个端口可以被重复使用吗 不需要如果这个进程不需要网络通信那么这个进程就不需要绑定端口的一个端口只能给某一个进程使用多个进程不能同时使用同一个端口 3. 字节序转换函数 当格式化的数据在两台使用不同字节序的主机之间直接传递时接收端必然错误的解释之。解决问题的方法是发送端总是把要发送的数据转换成大端字节序数据后再发送而接收端知道对方传送过来的数据总是采用大端字节序所以接收端可以根据自身采用的字节序决定是否对接收到的数据进行转换小端机转换大端机不转换。 网络字节顺序是 TCP/IP 中规定好的一种数据表示格式它与具体的 CPU 类型、操作系统等无关从而 可以保证数据在不同主机之间传输时能够被正确解释网络字节顺序采用大端排序方式。 BSD Socket提供了封装好的转换接口方便程序员使用。包括从主机字节序到网络字节序的转换函数 htons、htonl从网络字节序到主机字节序的转换函数ntohs、ntohl。 h - host 主机主机字节序
to - 转换成什么
n - network 网络字节序
s - short unsigned short
l - long unsigned int#include arpa/inet.h
// 转换端口
uint16_t htons(uint16_t hostshort); // 主机字节序 - 网络字节序
uint16_t ntohs(uint16_t netshort); // 网络字节序 - 主机字节序
// 转IP
uint32_t htonl(uint32_t hostlong); // 主机字节序 - 网络字节序
uint32_t ntohl(uint32_t netlong); // 网络字节序 - 主机字节序
4.socket 地址 socket地址其实是一个结构体封装端口号和IP等信息。后面的socket相关的api中需要使用到这个socket地址。客户端 - 服务器IP, Port 5. IP地址转换字符串ip-整数 主机、网络 字节序的转换
#include arpa/inet.h
// p:点分十进制的IP字符串n:表示network网络字节序的整数
int inet_pton(int af, const char *src, void *dst);af:地址族 AF_INET AF_INET6src:需要转换的点分十进制的IP字符串dst:转换后的结果保存在这个里面// 将网络字节序的整数转换成点分十进制的IP地址字符串
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);af:地址族 AF_INET AF_INET6src: 要转换的ip的整数的地址dst: 转换成IP地址字符串保存的地方size第三个参数的大小数组的大小返回值返回转换后的数据的地址字符串和 dst 是一样的
6. TCP通信流程
// TCP 通信的流程
// 服务器端 被动接受连接的角色
1. 创建一个用于监听的套接字- 监听监听有客户端的连接- 套接字这个套接字其实就是一个文件描述符
2. 将这个监听文件描述符和本地的IP和端口绑定IP和端口就是服务器的地址信息- 客户端连接服务器的时候使用的就是这个IP和端口
3. 设置监听监听的fd开始工作
4. 阻塞等待当有客户端发起连接解除阻塞接受客户端的连接会得到一个和客户端通信的套接字
fd
5. 通信- 接收数据- 发送数据
6. 通信结束断开连接// 客户端
1. 创建一个用于通信的套接字fd
2. 连接服务器需要指定连接的服务器的 IP 和 端口
3. 连接成功了客户端可以直接和服务器通信- 接收数据- 发送数据
4. 通信结束断开连接
7.套接字通信的服务器端实现
server.c
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include arpa/inet.hint main() {// 1.创建监听的套接字int fd socket(AF_INET,SOCK_STREAM,0);if(fd -1) {perror(socket);return -1;}// 2.绑定本地的IP portstruct sockaddr_in saddr;saddr.sin_family AF_INET;saddr.sin_addr.s_addr INADDR_ANY; // 0 0.0.0.0 对于0来说大端和小端是没有区别的的因此不需要转换saddr.sin_port htons(9999);//主机字节序转换成网络字节序int ret bind(fd,(struct sockaddr*)saddr,sizeof(saddr));if(ret -1) {perror(bind);return -1;}// 3.设置监听ret listen(fd,128);if(ret -1) {perror(listen);return -1;}// 4.阻塞并等待客户端的连接struct sockaddr_in caddr;int addrlen sizeof(caddr);int cfd accept(fd,(struct sockaddr*)caddr,addrlen);if(cfd -1) {perror(accept);return -1;}// 连接建立成功打印客户端的IP和端口信息char ip[32];printf(客户端的IP: %s,端口: %d\n,inet_ntop(AF_INET,caddr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(caddr.sin_port));// 5.通信while(1) {// 接收数据char buff[1024];int len recv(cfd,buff,sizeof(buff),0);if(len 0) {printf(client say: %s\n,buff);send(cfd,buff,len,0);}else if(len 0) {printf(客户端已经断开了连接...\n);break;}else{perror(recv);break;}}// 关掉文件描述符close(fd);close(cfd);return 0;
}
8.套接字通信的客户端实现
client.c
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include arpa/inet.hint main() {// 1.创建套接字int fd socket(AF_INET,SOCK_STREAM,0);if(fd -1) {perror(socket);return -1;}// 2.连接服务器IP portstruct sockaddr_in saddr;saddr.sin_family AF_INET;saddr.sin_port htons(9999);inet_pton(AF_INET,192.168.88.129,saddr.sin_addr.s_addr);int ret connect(fd,(struct sockaddr*)saddr,sizeof(saddr));if(ret -1) {perror(connect);return -1;}int number 0;// 3.通信while(1) {// 发送数据char buff[1024];sprintf(buff,你好呵呵哒,%d...\n,number);send(fd,buff,strlen(buff) 1,0);//接收数据memset(buff,0,sizeof(buff));int len recv(fd,buff,sizeof(buff),0);if(len 0) {printf(server say: %s\n,buff);}else if(len 0) {printf(服务器已经断开了连接...\n);break;}else{perror(recv);}sleep(1);}// 关闭文件描述符close(fd);return 0;
}