c2c电子商务网站的功能,做动态logo网站,某公司网站源码,软文发稿平台ARP 协议 ARP 协议#xff08;Address Resolution Protocol#xff09;通过 IP 地址查找对应的 MAC 地址。
当一个主机需要发送数据给另一个主机时#xff0c;它首先会检查本地的 ARP 缓存表#xff08;ARP cache#xff09;中是否存在目标主机的 MAC 地址。如果存在Address Resolution Protocol通过 IP 地址查找对应的 MAC 地址。
当一个主机需要发送数据给另一个主机时它首先会检查本地的 ARP 缓存表ARP cache中是否存在目标主机的 MAC 地址。如果存在则直接使用该 MAC 地址进行数据发送。如果不存在该 MAC 地址则需要使用 ARP 协议来获取目标主机的 MAC 地址。
主机发送一个 ARP 请求消息ARP Request广播到局域网上的所有主机。该请求中包含了源主机的 MAC 地址、IP 地址以及目标主机的 IP 地址。其他主机收到该请求后会检查自己的 IP 地址是否与目标主机的 IP 地址匹配。如果匹配则认为是 ARP 请求的目标主机并向源主机发送 ARP 响应消息ARP Reply其中包含了自己的 MAC 地址。源主机接收到 ARP 响应后将目标主机的 IP 地址和 MAC 地址的映射关系存储在本地的 ARP 缓存表中并使用目标主机的 MAC 地址进行数据发送。
通过这种方式ARP 协议实现了通过 IP 地址查找对应的 MAC 地址从而确保数据包能够正确地发送给目标主机。
字节序用联合体判断大端小端
/* 字节序字节在内存中存储的顺序。小端字节序数据的高位字节存储在内存的高位地址低位字节存储在内存的低位地址大端字节序数据的低位字节存储在内存的高位地址高位字节存储在内存的低位地址
*/// 通过代码检测当前主机的字节序
#include stdio.hint main() {union {short value; // 2字节char bytes[sizeof(short)]; // char[2]} test;test.value 0x0102;if((test.bytes[0] 1) (test.bytes[1] 2)) {printf(大端字节序\n);} else if((test.bytes[0] 2) (test.bytes[1] 1)) {printf(小端字节序\n);} else {printf(未知\n);}return 0;
}字节序转换函数
/*
网络通信时需要将主机字节序转换成网络字节序大端
另外一段获取到数据以后根据情况将网络字节序转换成主机字节序。// 转换端口
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); // 主机字节序 - 网络字节序*/ #include stdio.h
#include arpa/inet.hint main() {// htons 转换端口unsigned short a 0x0102;printf(a : %x\n, a);unsigned short b htons(a);printf(b : %x\n, b);printf(\n);// htonl 转换IPchar buf[4] {192, 168, 1, 100};int num *(int *)buf;int sum htonl(num);unsigned char *p (char *)sum;printf(%d %d %d %d\n, *p, *(p1), *(p2), *(p3));printf(\n);// ntohlunsigned char buf1[4] {1, 1, 168, 192};int num1 *(int *)buf1;int sum1 ntohl(num1);unsigned char *p1 (unsigned char *)sum1;printf(%d %d %d %d\n, *p1, *(p11), *(p12), *(p13));// ntohsreturn 0;
}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 是一样的#include stdio.h
#include arpa/inet.hint main() {// 创建一个ip字符串,点分十进制的IP地址字符串char buf[] 192.168.1.4;unsigned int num 0;// 将点分十进制的IP字符串转换成网络字节序的整数inet_pton(AF_INET, buf, num);unsigned char * p (unsigned char *)num;printf(%d %d %d %d\n, *p, *(p1), *(p2), *(p3));// 将网络字节序的IP整数转换成点分十进制的IP字符串char ip[16] ;const char * str inet_ntop(AF_INET, num, ip, 16);printf(str : %s\n, str);printf(ip : %s\n, str);printf(%d\n, ip str);return 0;
} TCP通信实现服务器端
// TCP 通信的服务器端#include stdio.h
#include arpa/inet.h
#include unistd.h
#include string.h
#include stdlib.hint main() {// 1.创建socket(用于监听的套接字)int lfd socket(AF_INET, SOCK_STREAM, 0);if(lfd -1) {perror(socket);exit(-1);}// 2.绑定struct sockaddr_in saddr;saddr.sin_family AF_INET;// inet_pton(AF_INET, 192.168.193.128, saddr.sin_addr.s_addr);saddr.sin_addr.s_addr INADDR_ANY; // 0.0.0.0saddr.sin_port htons(9999);int ret bind(lfd, (struct sockaddr *)saddr, sizeof(saddr));if(ret -1) {perror(bind);exit(-1);}// 3.监听ret listen(lfd, 8);if(ret -1) {perror(listen);exit(-1);}// 4.接收客户端连接struct sockaddr_in clientaddr;int len sizeof(clientaddr);int cfd accept(lfd, (struct sockaddr *)clientaddr, len);if(cfd -1) {perror(accept);exit(-1);}// 输出客户端的信息char clientIP[16];inet_ntop(AF_INET, clientaddr.sin_addr.s_addr, clientIP, sizeof(clientIP));unsigned short clientPort ntohs(clientaddr.sin_port);printf(client ip is %s, port is %d\n, clientIP, clientPort);// 5.通信char recvBuf[1024] {0};while(1) {// 获取客户端的数据int num read(cfd, recvBuf, sizeof(recvBuf));if(num -1) {perror(read);exit(-1);} else if(num 0) {printf(recv client data : %s\n, recvBuf);} else if(num 0) {// 表示客户端断开连接printf(clinet closed...);break;}char * data hello,i am server;// 给客户端发送数据write(cfd, data, strlen(data));}// 关闭文件描述符close(cfd);close(lfd);return 0;
}TCP通信实现客户端 client.c
// TCP通信的客户端
#include stdio.h
#include arpa/inet.h
#include unistd.h
#include string.h
#include stdlib.hint main() {// 1.创建套接字int fd socket(AF_INET, SOCK_STREAM, 0);if(fd -1) {perror(socket);exit(-1);}// 2.连接服务器端struct sockaddr_in serveraddr;serveraddr.sin_family AF_INET;inet_pton(AF_INET, 192.168.193.128, serveraddr.sin_addr.s_addr);serveraddr.sin_port htons(9999);int ret connect(fd, (struct sockaddr *)serveraddr, sizeof(serveraddr));if(ret -1) {perror(connect);exit(-1);}// 3. 通信char recvBuf[1024];int i 0;while(1) {sprintf(recvBuf, data : %d\n, i);// 给服务器端发送数据write(fd, recvBuf, strlen(recvBuf)1);int len read(fd, recvBuf, sizeof(recvBuf));if(len -1) {perror(read);exit(-1);} else if(len 0) {printf(recv server : %s\n, recvBuf);} else if(len 0) {// 表示服务器端断开连接printf(server closed...);break;}sleep(1);}// 关闭连接close(fd);return 0;
}server_process.c
#include stdio.h
#include arpa/inet.h
#include unistd.h
#include stdlib.h
#include string.h
#include signal.h
#include wait.h
#include errno.hvoid recyleChild(int arg) {while(1) {int ret waitpid(-1, NULL, WNOHANG);if(ret -1) {// 所有的子进程都回收了break;}else if(ret 0) {// 还有子进程活着break;} else if(ret 0){// 被回收了printf(子进程 %d 被回收了\n, ret);}}
}int main() {struct sigaction act;act.sa_flags 0;sigemptyset(act.sa_mask);act.sa_handler recyleChild;// 注册信号捕捉sigaction(SIGCHLD, act, NULL);// 创建socketint lfd socket(PF_INET, SOCK_STREAM, 0);if(lfd -1){perror(socket);exit(-1);}struct sockaddr_in saddr;saddr.sin_family AF_INET;saddr.sin_port htons(9999);saddr.sin_addr.s_addr INADDR_ANY;// 绑定int ret bind(lfd,(struct sockaddr *)saddr, sizeof(saddr));if(ret -1) {perror(bind);exit(-1);}// 监听ret listen(lfd, 128);if(ret -1) {perror(listen);exit(-1);}// 不断循环等待客户端连接while(1) {struct sockaddr_in cliaddr;int len sizeof(cliaddr);// 接受连接int cfd accept(lfd, (struct sockaddr*)cliaddr, len);if(cfd -1) {if(errno EINTR) {continue;}perror(accept);exit(-1);}// 每一个连接进来创建一个子进程跟客户端通信pid_t pid fork();if(pid 0) {// 子进程// 获取客户端的信息char cliIp[16];inet_ntop(AF_INET, cliaddr.sin_addr.s_addr, cliIp, sizeof(cliIp));unsigned short cliPort ntohs(cliaddr.sin_port);printf(client ip is : %s, prot is %d\n, cliIp, cliPort);// 接收客户端发来的数据char recvBuf[1024];while(1) {int len read(cfd, recvBuf, sizeof(recvBuf));if(len -1) {perror(read);exit(-1);}else if(len 0) {printf(recv client : %s\n, recvBuf);} else if(len 0) {printf(client closed....\n);break;}write(cfd, recvBuf, strlen(recvBuf) 1);}close(cfd);exit(0); // 退出当前子进程}}close(lfd);return 0;
}#include iostream
#include fstream
#include string
#include list
using namespace std;// 学生类
class Student {
private:string name;int regID;int score;public:Student(string name, int regID, int score) {this-name name;this-regID regID;this-score score;}string getName() const {return name;}int getRegID() const {return regID;}int getScore() const {return score;}
};// HashMap类
class HashMap {
private:static const int SIZE 10;listStudent* hashTable[SIZE];int hashCode(int regID) {return regID % SIZE;}public:Student* get(int regID) {int index hashCode(regID);for (Student* student : hashTable[index]) {if (student-getRegID() regID) {return student;}}return nullptr;}bool put(Student* student) {int regID student-getRegID();int index hashCode(regID);for (Student* s : hashTable[index]) {if (s-getRegID() regID) {return false; // 已存在相同学号的学生}}hashTable[index].push_back(student);return true;}
};int main() {HashMap studentMap;// 读取数据文件ifstream file(data.txt);if (file) {string line;while (getline(file, line)) {size_t pos1 line.find(,);string name line.substr(0, pos1);size_t pos2 line.find(,, pos1 1);int regID stoi(line.substr(pos1 1, pos2 - pos1 - 1));int score stoi(line.substr(pos2 1));// 创建Student对象并添加到HashMap中Student* student new Student(name, regID, score);studentMap.put(student);}file.close();// 输入学号查询学生信息int regID;cout 请输入学号;cin regID;Student* student studentMap.get(regID);if (student) {cout 姓名 student-getName() endl;cout 学号 student-getRegID() endl;cout 成绩 student-getScore() endl;} else {cout 未找到该学号对应的学生信息 endl;}} else {cout 无法打开数据文件 endl;}return 0;
}