为了账号安全,请及时绑定邮箱和手机立即绑定

作业社区

探索学习新天地,共享知识资源!

0 提交作业
0 布置作业
0 满分作业
得分 100
学习任务

慕神4583458 的学生作业:

【图片】 server.c #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUF_SZ 1024 enum LOGIN_STATUS { LOGIN_FAIL = 0, LOGIN_SUCCESS = 1, }; typedef struct message_thread_arg { char *ip; unsigned char status; struct sockaddr_in *recv_addr; } message_thread_arg_t; int init_socket(char *ip, char *port) { int socketfd; socketfd = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in addr_in; addr_in.sin_family = AF_INET; addr_in.sin_port = htons(atoi(port)); addr_in.sin_addr.s_addr = inet_addr(ip); int ret = bind(socketfd, (struct sockaddr *)&addr_in, sizeof(addr_in)); return socketfd; } void recv_data(int socketfd) { int bytes; char buf[1024]; struct sockaddr_in recv_addr; socklen_t len = sizeof(struct sockaddr); while(1) { printf("wait data====\n"); memset(buf, 0, sizeof(buf)); bytes = recvfrom(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&recv_addr, &len); if (bytes == -1) { perror("[ERROR] recvfrom():"); exit(EXIT_FAILURE); } printf("ip = %s port = %d\n", inet_ntoa(recv_addr.sin_addr), ntohs(recv_addr.sin_port)); printf("Recv size = %d buf = %s\n", bytes, buf); if (strcmp(buf, "quit") == 0) break; } pthread_exit(NULL); } void *message_thread(void *arg) { message_thread_arg_t *thread_arg = (message_thread_arg_t *)arg; int new_socketfd = init_socket(thread_arg->ip, "0"); sendto(new_socketfd, &thread_arg->status, sizeof(thread_arg->status), 0, (struct sockaddr *)thread_arg->recv_addr, sizeof(*thread_arg->recv_addr)); recv_data(new_socketfd); } int user_login(char *ip, char *port) { int socketfd = init_socket(ip, port); int new_socketfd; int bytes; char buf[20]; struct sockaddr_in recv_addr; socklen_t len = sizeof(struct sockaddr); unsigned char status = 0; pthread_t tid; message_thread_arg_t thread_arg; while(1) { memset(buf, 0, sizeof(buf)); bytes = recvfrom(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&recv_addr, &len); if (bytes == -1) { perror("[ERROR] recvfrom():"); exit(EXIT_FAILURE); } status = strcmp(buf, "root") == 0 ? LOGIN_SUCCESS : LOGIN_FAIL; if (status == LOGIN_SUCCESS) { printf("login success\n"); thread_arg.ip = ip; thread_arg.recv_addr = &recv_addr; thread_arg.status = status; tid = pthread_create(&tid, NULL, message_thread, (void *)&thread_arg); pthread_detach(tid); } else { printf("login fail\n"); sendto(socketfd, &status, sizeof(status), 0, (struct sockaddr *)&recv_addr, len); } } return new_socketfd; } int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, " %s ip port", argv[0]); exit(EXIT_FAILURE); } int socketfd = user_login(argv[1], argv[2]); return 0; } client.c #include #include #include #include #include #include #include #include #include #include #include #define BUF_SZ 1024 enum LOGIN_STATUS { LOGIN_FAIL = 0, LOGIN_SUCCESS = 1, }; int init_socket(char *ip, char *port) { int socketfd; socketfd = socket(AF_INET, SOCK_DGRAM, 0); // struct sockaddr_in addr_in; // addr_in.sin_family = AF_INET; // addr_in.sin_port = htons(atoi(port)); // addr_in.sin_addr.s_addr = inet_addr(ip); // int ret = bind(socketfd, (struct sockaddr *)&addr_in, sizeof(addr_in)); return socketfd; } void send_data(int socketfd, struct sockaddr_in *paddr_in) { int ret; char buf[1024]; while(1) { printf("root:>"); fflush(NULL); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = '\0'; ret = sendto(socketfd, buf, strlen(buf), 0, (struct sockaddr *)paddr_in, sizeof(*paddr_in)); if (ret == -1) { perror("[ERROR] sendto():"); exit(EXIT_FAILURE); } if (strcmp(buf, "quit") == 0) { exit(EXIT_SUCCESS); } } } void user_login(char *ip, char *port) { int socketfd = init_socket(ip, port); int bytes; char buf[1024]; struct sockaddr_in send_addr; send_addr.sin_family = AF_INET; send_addr.sin_addr.s_addr = inet_addr(ip); send_addr.sin_port = htons(atoi(port)); struct sockaddr_in recv_addr; socklen_t len = sizeof(struct sockaddr); short status = 0; while(1) { putchar('>'); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = '\0'; sendto(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&send_addr, sizeof(send_addr)); bytes = recvfrom(socketfd, &status, sizeof(status), 0, (struct sockaddr *)&recv_addr, &len); if (bytes == -1) { perror("[ERROR] recvfrom():"); exit(EXIT_FAILURE); } if (status == LOGIN_SUCCESS) break; } printf("break"); send_data(socketfd, &recv_addr); } int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, " %s ip port", argv[0]); exit(EXIT_FAILURE); } user_login(argv[1], argv[2]); return 0; }

得分 100
学习任务

SamstagBaron 的学生作业:

#include #include #include #include #include #include #include #include #include #define mque "." #define object_id 0xaa struct msgbuf{ long mytype; char message[100]; }; long types[2] = {100,200}; int main(){ key_t key = ftok(mque,object_id); if(key==-1){ perror("[ERROR] ftok() : "); exit(EXIT_FAILURE); } int msgid = msgget(key,IPC_CREAT|0666); if(msgid==-1){ perror("[ERROR] msgget() : "); exit(EXIT_FAILURE); } printf("Created message queue %d \n",msgid); pid_t pid[2]; pid[0] = fork(); if(pid[0]==-1){ perror("[ERROR] fork() : "); exit(EXIT_FAILURE); }else if(pid[0]==0){ struct msgbuf cbuff; cbuff.mytype = types[0]; while(1){ ssize_t rbytes = msgrcv(msgid,(void*)&cbuff,sizeof(cbuff.message),types[0],0); if(rbytes==-1){ perror("[ERROR] msgrcv() : "); exit(EXIT_FAILURE); } if(strncmp(cbuff.message,"quit",4)==0){ printf("Child process %d exited\n",getpid()); exit(EXIT_SUCCESS); } cbuff.message[rbytes]='\0'; printf("child %d get message %s\n",getpid(),cbuff.message); } }else if(pid[0]>0){ pid[1] = fork(); if(pid[1]==-1){ perror("[ERROR] fork() : "); exit(EXIT_FAILURE); }else if(pid[1]==0){ struct msgbuf cbuff; cbuff.mytype = types[1]; while(1){ ssize_t rbytes = msgrcv(msgid,(void*)&cbuff,sizeof(cbuff.message),types[1],0); if(rbytes==-1){ perror("[ERROR] msgrcv() : "); exit(EXIT_FAILURE); } if(strncmp(cbuff.message,"quit",4)==0){ printf("Child process %d exited\n",getpid()); exit(EXIT_SUCCESS); } cbuff.message[rbytes]='\0'; printf("child %d get message %s\n",getpid(),cbuff.message); } }else if(pid[1]>0){ struct msgbuf pbuff; int idx = 0; while(1){ scanf("%s",pbuff.message); pbuff.mytype = types[idx]; msgsnd(msgid,(const void*)&pbuff,strlen(pbuff.message),0); if(strcmp(pbuff.message,"quit")==0){ pbuff.mytype = types[idx^1]; msgsnd(msgid,(const void*)&pbuff,strlen(pbuff.message),0); while(wait(NULL)!=-1); printf("Main process exited\n"); break; } idx^=1; } } } int res = msgctl(msgid,IPC_RMID,NULL); if(res == -1){ perror("[ERROR] msgctl() : "); exit(EXIT_FAILURE); } printf("Erased message queue %d \n",msgid); return 0; } 【图片】

得分 100
学习任务

慕神4583458 的学生作业:

【图片】 upd.server.c #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUF_SZ 1024 enum LOGIN_STATUS { LOGIN_FAIL = 0, LOGIN_SUCCESS = 1, }; int init_socket(char *ip, char *port) { int socketfd; socketfd = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in addr_in; addr_in.sin_family = AF_INET; addr_in.sin_port = htons(atoi(port)); addr_in.sin_addr.s_addr = inet_addr(ip); int ret = bind(socketfd, (struct sockaddr *)&addr_in, sizeof(addr_in)); return socketfd; } int user_login(char *ip, char *port) { int socketfd = init_socket(ip, port); int new_socketfd; int bytes; char buf[20]; struct sockaddr_in recv_addr; socklen_t len = sizeof(struct sockaddr); short status = 0; while(1) { memset(buf, 0, sizeof(buf)); bytes = recvfrom(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&recv_addr, &len); if (bytes == -1) { perror("[ERROR] recvfrom():"); exit(EXIT_FAILURE); } status = strcmp(buf, "root") == 0 ? LOGIN_SUCCESS : LOGIN_FAIL; if (status == LOGIN_SUCCESS) { printf("login success\n"); pid_t pid = fork(); if (pid == 0) { close(socketfd); new_socketfd = init_socket(ip, "0"); sendto(new_socketfd, &status, sizeof(status), 0, (struct sockaddr *)&recv_addr, sizeof(recv_addr)); printf("close child fd\n"); break; } } else { printf("login fail\n"); sendto(socketfd, &status, sizeof(status), 0, (struct sockaddr *)&recv_addr, len); } } return new_socketfd; } void recv_data(int socketfd) { int bytes; char buf[1024]; struct sockaddr_in recv_addr; socklen_t len = sizeof(struct sockaddr); while(1) { printf("wait data====\n"); memset(buf, 0, sizeof(buf)); bytes = recvfrom(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&recv_addr, &len); if (bytes == -1) { perror("[ERROR] recvfrom():"); exit(EXIT_FAILURE); } printf("ip = %s port = %d\n", inet_ntoa(recv_addr.sin_addr), ntohs(recv_addr.sin_port)); printf("Recv size = %d buf = %s\n", bytes, buf); if (strcmp(buf, "quit") == 0) break; } close(socketfd); exit(EXIT_SUCCESS); } void sig_handler(int signum) { wait(NULL); printf("process exit, signum = %d \n", signum); } int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, " %s ip port", argv[0]); exit(EXIT_FAILURE); } if (signal(SIGCHLD, sig_handler) == SIG_ERR) { perror("signal():"); exit(EXIT_FAILURE); } int socketfd = user_login(argv[1], argv[2]); recv_data(socketfd); return 0; } udp.client.c #include #include #include #include #include #include #include #include #include #include #include #define BUF_SZ 1024 enum LOGIN_STATUS { LOGIN_FAIL = 0, LOGIN_SUCCESS = 1, }; int init_socket(char *ip, char *port) { int socketfd; socketfd = socket(AF_INET, SOCK_DGRAM, 0); // struct sockaddr_in addr_in; // addr_in.sin_family = AF_INET; // addr_in.sin_port = htons(atoi(port)); // addr_in.sin_addr.s_addr = inet_addr(ip); // int ret = bind(socketfd, (struct sockaddr *)&addr_in, sizeof(addr_in)); return socketfd; } void send_data(int socketfd, struct sockaddr_in *paddr_in) { int ret; char buf[1024]; while(1) { printf("root:>"); fflush(NULL); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = '\0'; ret = sendto(socketfd, buf, strlen(buf), 0, (struct sockaddr *)paddr_in, sizeof(*paddr_in)); if (ret == -1) { perror("[ERROR] sendto():"); exit(EXIT_FAILURE); } if (strcmp(buf, "quit") == 0) { exit(EXIT_SUCCESS); } } } void user_login(char *ip, char *port) { int socketfd = init_socket(ip, port); int bytes; char buf[1024]; struct sockaddr_in send_addr; send_addr.sin_family = AF_INET; send_addr.sin_addr.s_addr = inet_addr(ip); send_addr.sin_port = htons(atoi(port)); struct sockaddr_in recv_addr; socklen_t len = sizeof(struct sockaddr); short status = 0; while(1) { putchar('>'); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = '\0'; sendto(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&send_addr, sizeof(send_addr)); bytes = recvfrom(socketfd, &status, sizeof(status), 0, (struct sockaddr *)&recv_addr, &len); if (bytes == -1) { perror("[ERROR] recvfrom():"); exit(EXIT_FAILURE); } if (status == LOGIN_SUCCESS) break; } printf("break"); send_data(socketfd, &recv_addr); } int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, " %s ip port", argv[0]); exit(EXIT_FAILURE); } user_login(argv[1], argv[2]); return 0; }

得分 100
学习任务

阿大月 的学生作业:

当两台主机(A: 192.168.0.88 和 B: 192.168.0.66)处于同一局域网(相同子网)时,它们的通信过程主要依赖**数据链路层(Layer 2)**的协议(如以太网和ARP),而非通过路由器(Layer 3设备)。以下是详细原理和流程: 判断目标是否在同一子网 原理:主机A通过子网掩码(如 255.255.255.0)计算目标IP是否与自己在同一子网。 A的IP:192.168.0.88,子网掩码:255.255.255.0 → 子网地址是 192.168.0.0/24。 B的IP:192.168.0.66 → 也属于 192.168.0.0/24。 结论:无需通过网关(路由器),直接进行二层通信。 ARP协议:IP地址到MAC地址的映射 目的:主机A需要知道主机B的MAC地址才能发送以太网帧。 流程: 检查ARP缓存: 主机A先查看本地ARP缓存表,是否有 192.168.0.66 对应的MAC地址。 广播ARP请求: 若未找到,主机A发送一个广播帧(目标MAC为 FF:FF:FF:FF:FF:FF),携带以下信息: ARP Request: Who has 192.168.0.66? Tell 192.168.0.88 (MAC: AA:AA:AA:AA:AA:AA) ARP响应: 主机B收到广播后,发现目标IP是自己,向主机A回复单播ARP响应: ARP Reply: 192.168.0.66 is at BB:BB:BB:BB:BB:BB 更新ARP缓存: 主机A将 192.168.0.66 → BB:BB:BB:BB:BB:BB 存入本地ARP缓存,后续通信无需重复查询。 3. 构建以太网帧 帧结构: 目标MAC:BB:BB:BB:BB:BB:BB(主机B的MAC地址)。 源MAC:AA:AA:AA:AA:AA:AA(主机A的MAC地址)。 类型字段:0x0800(表示上层协议是IPv4)。 数据载荷:封装IP数据包(如ICMP请求、TCP/UDP报文等)。 数据帧的传输(交换机工作原理) 设备角色:局域网内的交换机(Layer 2设备)负责转发帧。 流程: 接收帧: 主机A通过网卡将帧发送到交换机。 学习MAC地址表: 交换机会记录主机A的MAC地址(AA:AA:AA:AA:AA:AA)和对应的端口。 查找目标MAC: 交换机检查目标MAC BB:BB:BB:BB:BB:BB 是否存在于MAC地址表中。 如果存在,直接从对应端口转发帧。 如果不存在,向所有端口广播(洪泛)帧(除了源端口)。 主机B接收帧: 主机B的网卡识别目标MAC是自己的地址,接收并解封装帧。 上层协议处理(以ICMP为例) 假设主机A向主机B发送一个 ping 请求(ICMP协议): IP层: 构建IP数据包,源IP 192.168.0.88,目标IP 192.168.0.66。 ICMP层: 封装ICMP Echo Request报文。 主机B响应: 主机B生成ICMP Echo Reply,通过类似流程反向发送给主机A。 关键特点总结 无需路由器: 同一子网的通信完全在二层完成,不涉及IP路由。 依赖MAC地址: 交换机基于MAC地址表转发帧,而非IP地址。 广播与单播: ARP请求是广播,实际数据传输是单播。 低延迟: 局域网内通信延迟通常低于1ms(无跨设备或跨网络开销)。

微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号