当前位置: 首页> 健康> 美食 > 唐山网站公司建站_哈尔滨网站建设方案策划_线上产品推广方案_茂名网络推广

唐山网站公司建站_哈尔滨网站建设方案策划_线上产品推广方案_茂名网络推广

时间:2025/7/9 3:28:02来源:https://blog.csdn.net/hyd_ashely/article/details/146078416 浏览次数:1次
唐山网站公司建站_哈尔滨网站建设方案策划_线上产品推广方案_茂名网络推广

TCP与UDP区别

  • UDP:用户数据报协议,面向无连接,可以单播,多播,广播, 面向数据报,不可靠
  • TCP:传输控制协议,面向连接的,可靠的,基于字节流,仅支持单播传输

在这里插入图片描述

socket通信

是对网络中不同主机上的应用程序进程之间进行双向通信端点的抽象

字节序

**小端字节序:**低位存在内存的低位
大端字节序:低位存在内存的高位
eg:小端
0x01 02 03 04
01是高位有效字节,04是低位,那么在内存中是这么存的:
0x04 0x03 0x02 0x01

字节序转化内函数

h  - host 主机,主机字节序 
to - 转换成什么 
n  - network 网络字节序 
s  - short unsigned short 
l  - long unsigned int#include <arpa/inet.h> 
// 转换端口 short型,2个字节
uint16_t htons(uint16_t hostshort); // 主机字节序 => 网络字节序 
uint16_t ntohs(uint16_t netshort); // 主机字节序 => 网络字节序 
// 转IP int型,4个字节
uint32_t htonl(uint32_t hostlong); // 主机字节序 => 网络字节序 
uint32_t ntohl(uint32_t netlong); // 主机字节序 => 网络字节序

ip地址转换------点分十进制<–>网络通信2进制

通常,人们习惯用可读性好的字符串来表示 IP 地址,比如用点分十进制字符串表示 IPv4 地址,以及用十六进制字符串表示 IPv6> 地址。但编程中我们需要先把它们转化为整数(二进制数)方能使用。而记录日志时则相反,我们要把整数表示的 IP 地址转化为可读的字符串

新版:同时适用于IPV4和IPV6* 字母含义* `p`:点分十进制的IP字符串* `n`:表示network,网络字节序的整数
* `int inet_pton(int af, const char *src, void *dst); `* 使用`man inet_pton`查看帮助* 功能:将点分十进制的IP地址字符串,转换成网络字节序的整数* 参数* `af`:地址族* IPV4:`AF_INET`* IPV6:`AF_INET6(IPV6)`* `src`:需要转换的点分十进制的IP字符串* `dst`:转换后的结果保存在这个里面* 返回值* 1:成功* 0:源IP地址有误* -1:地址族包含不可用的地址协议
* `const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);`* 使用`man inet_ntop`查看帮助* 功能:将网络字节序的整数,转换成点分十进制的IP地址字符串* 参数* `af`:地址族* IPV4:`AF_INET`* IPV6:`AF_INET6(IPV6)`* `src`:要转换的ip的整数的地址* `dst`:转换成IP地址字符串保存的地方* `size`:第三个参数的大小(数组的大小)* 返回值:返回转换后的数据的地址(字符串),和 dst 是一样的

把IP和port打包为一个socket地址

协议族地址族描述
PF_UNIXAF_UNIXUNIX本地域协议族
PF_INETAF_INETTCP/IPV4z协议族
PF_INET6AF_INET6tcp/IPV6协议族
//socket网络通信接口中表示socket地址的是一个结构体,他的地址作为通信用,但一般用下面的改进版本,再转换成这个
#include <bits/socket.h> 
struct sockaddr { sa_family_t sa_family; char sa_data[14]; 
};typedef unsigned short int sa_family_t;

为了兼容IPV6,新的socketaddr_in

// IPV4
#include <netinet/in.h> 
-----------------------------------------------------------------------
struct sockaddr_in { sa_family_t sin_family; /* __SOCKADDR_COMMON(sin_) */ in_port_t sin_port; /* Port number. */ struct in_addr sin_addr; /* Internet address. */ /* Pad to size of `struct sockaddr'. */ unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)]; 
};
-----------------------------------------------------------------------
struct in_addr { in_addr_t s_addr; 
};// IPV6
struct sockaddr_in6 { sa_family_t sin6_family; in_port_t sin6_port; /* Transport layer port # */ uint32_t sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* IPv6 scope-id */ 
};// 相关定义
typedef unsigned short uint16_t; 
typedef unsigned int uint32_t; 
typedef uint16_t in_port_t; 
typedef uint32_t in_addr_t; 
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))

TCP通信框架

在这里插入图片描述

实例,客户端和服务端通信

服务端:
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <string>using namespace std;
#define SERVERIP "192.168.226.129"
#define PORT 9999//服务器端
int main() {//创建socket套接字,形成监听fdint lfd = socket(AF_INET, SOCK_STREAM, 0);if (lfd == -1) {perror("socket");return -1;}//形成一个端,把ip和port打包好在新版的sockaddr_in结构体中struct sockaddr_in mServ;mServ.sin_family = AF_INET;mServ.sin_port = htons(PORT);//将上面字符串形式的点分十进制IP转化为网络字节序的IPinet_pton(AF_INET, SERVERIP, &mServ.sin_addr.s_addr);//将上面的打包的端和监听fd绑定int ret = bind(lfd, (struct sockaddr*)&mServ, sizeof(mServ));if (ret == -1) {perror("bind");return -1;}//监听fd开始监听,后面的值代表未连接和连接的数ret = listen(lfd, 128);if (ret == -1) {perror("listen");return -1;}cout << "服务器启动成功,等待连接...." << endl;//接受连接,返回一个新的真正用于交换数据的fdstruct sockaddr_in client;socklen_t client_addr_len = sizeof(client);int cfd = accept(lfd, (struct sockaddr*)&client, &client_addr_len);if (cfd == -1) {perror("accept");return -1;}//输出客户端的ip和端口char clinet_ip[16];inet_ntop(AF_INET, &client.sin_addr.s_addr, clinet_ip, sizeof(clinet_ip));//将n->p的ip写到clinet_ip中int clinet_port = ntohs(client.sin_port);cout << "连接成功!客户端IP:" << clinet_ip << " 端口:" << clinet_port << endl;//读取客户端的数据char buf[1024];char writer[1024];while(1) {int read_len = read(cfd, buf, sizeof(buf));if (read_len == -1) {perror("read");return -1;}else if (read_len == 0) {cout << "客户端断开连接!" << endl;break;}else if (read_len >0) cout << "客户端发来的数据:" << buf << endl;//向客户端发送数据cout << "请输入要发送的数据:";cin >> writer;write(cfd, writer, sizeof(writer));}   close(cfd);close(lfd);return 0;
}
客户端
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <string>using namespace std;
#define SERVERIP "192.168.226.129"
#define PORT 9999//客户端
int main() {int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd == -1) {perror("client_socket");return -1;}//打包client的IP和PORT信息struct sockaddr_in clit;clit.sin_family = AF_INET;clit.sin_port = htons(PORT);inet_pton(AF_INET, SERVERIP, &clit.sin_addr.s_addr);//客户端开始连接服务器int ret = connect(fd, (struct sockaddr*)&clit, sizeof(clit));if (ret == -1) {perror("client connect");return -1;}cout << "客户端开始连接...." << endl;//开始通信char writer[1024];char buf[1024];while(1) {cout << "请输入发给服务器的内容:";cin >> writer;ret = write(fd, writer, sizeof(writer));if (ret == -1) {perror("client write");return -1;}ret = read(fd, buf, sizeof(buf));if (ret == -1) {perror("client read");return -1;} else if (ret == 0) {cout << "服务器断开连接" << endl;break;} else  cout << "受到客户端返回信息:" << buf << endl;}close(fd);return 0;
}
关键字:唐山网站公司建站_哈尔滨网站建设方案策划_线上产品推广方案_茂名网络推广

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: