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

作业社区

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

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

jelasin 的学生作业:

TCP流式协议特性 TCP是面向流的协议,它将数据看作连续的字节流,而不是独立的数据包。发送端的多次写操作可能被接收端的一次读操作接收,或者发送端的一次写操作可能需要接收端多次读操作才能完整接收。 Nagle算法优化 为了提高网络效率,TCP实现了Nagle算法。该算法会将小的数据包合并成较大的数据包再发送,这样可以减少网络中的小包数量,提高传输效率。但这也导致了原本独立的数据包被合并,在接收端出现粘包现象。 TCP缓冲区机制 发送端和接收端都有缓冲区。发送端的缓冲区可能会积累多个小的数据包后一起发送;接收端的缓冲区也可能一次接收到多个数据包的内容。这种缓冲机制虽然提高了效率,但也是造成粘包的重要原因。 网络传输延迟和拥塞控制 在网络传输过程中,由于延迟、拥塞控制等因素,原本分开发送的数据包可能会在传输路径中被合并或重新组织。 应用层读取方式 应用程序在读取数据时,如果一次读取的字节数超过了单个消息的长度,就会读取到多个消息的内容,造成粘包。 //client #include #include #include #include #include #include #define PORT 8080 #define SERVER_IP "127.0.0.1" int main() { int sock = 0; struct sockaddr_in serv_addr; // 创建socket if ((sock = socket(AF_INET, SOCK_STREAM, 0))

得分 100
学习任务

jelasin 的学生作业:

#include #include #include #include #include #include #include #include #define SERVER_PORT 8080 #define BACKLOG 10 #define BUFFER_SIZE 1024 // 客户端信息结构体 typedef struct { int client_socket; struct sockaddr_in client_addr; } client_info_t; // 线程处理函数:处理单个客户端连接 void* handle_client(void* arg) { client_info_t* client_info = (client_info_t*)arg; int client_socket = client_info->client_socket; struct sockaddr_in client_addr = client_info->client_addr; printf("[线程 %ld] 开始处理客户端: %s:%d\n", pthread_self(), inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); char buffer[BUFFER_SIZE]; ssize_t bytes_received; // 与客户端通信循环 while (1) { bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0); if (bytes_received > 0) { buffer[bytes_received] = '\0'; printf("[线程 %ld] 收到消息: %s", pthread_self(), buffer); // 简单回显 - 增加响应缓冲区大小以避免截断警告 char response[BUFFER_SIZE + 64]; // 为格式化字符串预留额外空间 snprintf(response, sizeof(response), "[线程 %ld] Echo: %s", pthread_self(), buffer); send(client_socket, response, strlen(response), 0); } else if (bytes_received == 0) { printf("[线程 %ld] 客户端断开连接: %s:%d\n", pthread_self(), inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } else { perror("recv失败"); break; } } close(client_socket); free(client_info); printf("[线程 %ld] 客户端处理完成,线程退出\n", pthread_self()); pthread_exit(NULL); } // 函数:创建和绑定服务器socket int create_and_bind_server(const char* ip, int port) { int server_socket; struct sockaddr_in server_addr; int reuse = 1; // 1. 创建套接字 server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { perror("socket创建失败"); return -1; } printf("Socket创建成功 (fd: %d)\n", server_socket); // 设置SO_REUSEADDR选项 if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) { perror("setsockopt失败"); close(server_socket); return -1; } // 2. 配置服务器地址结构 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); // 根据IP参数设置绑定地址 if (ip == NULL || strcmp(ip, "0.0.0.0") == 0) { server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有可用接口 printf("配置为监听所有接口 (0.0.0.0:%d)\n", port); } else { if (inet_aton(ip, &server_addr.sin_addr) == 0) { printf("无效的IP地址: %s\n", ip); close(server_socket); return -1; } printf("配置为监听指定IP (%s:%d)\n", ip, port); } // 3. 绑定IP地址和端口号 if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { perror("bind失败"); close(server_socket); return -1; } printf("成功绑定到端口 %d\n", port); return server_socket; } int main(int argc, char *argv[]) { int server_socket; // 解析命令行参数 char *server_ip = NULL; int server_port = SERVER_PORT; if (argc >= 2) { server_port = atoi(argv[1]); if (server_port 65535) { printf("无效端口号: %s\n", argv[1]); exit(EXIT_FAILURE); } } if (argc >= 3) { server_ip = argv[2]; } // 创建和绑定服务器socket server_socket = create_and_bind_server(server_ip, server_port); if (server_socket == -1) { exit(EXIT_FAILURE); } // 4. 开始监听 if (listen(server_socket, BACKLOG) == -1) { perror("listen失败"); close(server_socket); exit(EXIT_FAILURE); } printf("服务器开始监听,等待客户端连接...\n"); printf("监听队列大小: %d (最多可同时等待 %d 个连接)\n", BACKLOG, BACKLOG); printf("服务器地址: %s:%d\n", server_ip ? server_ip : "0.0.0.0", server_port); // 5. 主循环:接受客户端连接 while (1) { printf("\n等待新的客户端连接...\n"); // 接受客户端连接 struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); int client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_len); if (client_socket == -1) { perror("accept失败"); continue; } printf("客户端连接成功: %s:%d (socket fd: %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), client_socket); // 创建结构体保存客户端信息 client_info_t* client_info = (client_info_t*)malloc(sizeof(client_info_t)); if (client_info == NULL) { perror("malloc失败"); close(client_socket); continue; } client_info->client_socket = client_socket; client_info->client_addr = client_addr; // 创建线程处理客户端连接 pthread_t tid; if (pthread_create(&tid, NULL, handle_client, client_info) != 0) { perror("pthread_create失败"); close(client_socket); free(client_info); } else { // 分离线程,在线程结束时自动回收资源 pthread_detach(tid); printf("为客户端 %s:%d 创建处理线程 %ld\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), tid); } } close(server_socket); return 0; } #include #include #include #include #include #include #include #define SERVER_IP "127.0.0.1" #define SERVER_PORT 8080 #define BUFFER_SIZE 1024 int main() { int client_socket; struct sockaddr_in server_addr; char buffer[BUFFER_SIZE]; ssize_t bytes_received; // 创建套接字 client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket == -1) { perror("socket创建失败"); exit(EXIT_FAILURE); } // 配置服务器地址结构 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // 连接到服务器 if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { perror("连接服务器失败"); close(client_socket); exit(EXIT_FAILURE); } printf("成功连接到服务器 %s:%d\n", SERVER_IP, SERVER_PORT); printf("输入消息发送到服务器 (输入'quit'退出):\n"); while (1) { // 从用户获取输入 printf("客户端> "); fflush(stdout); if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) { break; } // 检查退出条件 if (strncmp(buffer, "quit", 4) == 0) { printf("客户端退出...\n"); break; } // 发送消息到服务器 ssize_t bytes_sent = send(client_socket, buffer, strlen(buffer), 0); if (bytes_sent == -1) { perror("发送消息失败"); break; } // 接收服务器响应 bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0); if (bytes_received > 0) { buffer[bytes_received] = '\0'; // 移除消息末尾的换行符(如果有的话) char *newline = strchr(buffer, '\n'); if (newline) *newline = '\0'; printf("服务器响应: %s\n", buffer); } else if (bytes_received == 0) { printf("服务器关闭了连接\n"); break; } else { perror("接收消息失败"); break; } } // 关闭套接字 close(client_socket); return 0; }

得分 100
学习任务

jelasin 的学生作业:

#include #include #include #include #include #include #include #include #define SERVER_PORT 8080 #define BACKLOG 10 #define BUFFER_SIZE 1024 // 客户端信息结构体 typedef struct { int client_socket; struct sockaddr_in client_addr; } client_info_t; // 线程处理函数:处理单个客户端连接 void* handle_client(void* arg) { client_info_t* client_info = (client_info_t*)arg; int client_socket = client_info->client_socket; struct sockaddr_in client_addr = client_info->client_addr; printf("[线程 %ld] 开始处理客户端: %s:%d\n", pthread_self(), inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); char buffer[BUFFER_SIZE]; ssize_t bytes_received; // 与客户端通信循环 while (1) { bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0); if (bytes_received > 0) { buffer[bytes_received] = '\0'; printf("[线程 %ld] 收到消息: %s", pthread_self(), buffer); // 简单回显 - 增加响应缓冲区大小以避免截断警告 char response[BUFFER_SIZE + 64]; // 为格式化字符串预留额外空间 snprintf(response, sizeof(response), "[线程 %ld] Echo: %s", pthread_self(), buffer); send(client_socket, response, strlen(response), 0); } else if (bytes_received == 0) { printf("[线程 %ld] 客户端断开连接: %s:%d\n", pthread_self(), inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } else { perror("recv失败"); break; } } close(client_socket); free(client_info); printf("[线程 %ld] 客户端处理完成,线程退出\n", pthread_self()); pthread_exit(NULL); } // 函数:创建和绑定服务器socket int create_and_bind_server(const char* ip, int port) { int server_socket; struct sockaddr_in server_addr; int reuse = 1; // 1. 创建套接字 server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { perror("socket创建失败"); return -1; } printf("Socket创建成功 (fd: %d)\n", server_socket); // 设置SO_REUSEADDR选项 if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) { perror("setsockopt失败"); close(server_socket); return -1; } // 2. 配置服务器地址结构 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); // 根据IP参数设置绑定地址 if (ip == NULL || strcmp(ip, "0.0.0.0") == 0) { server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有可用接口 printf("配置为监听所有接口 (0.0.0.0:%d)\n", port); } else { if (inet_aton(ip, &server_addr.sin_addr) == 0) { printf("无效的IP地址: %s\n", ip); close(server_socket); return -1; } printf("配置为监听指定IP (%s:%d)\n", ip, port); } // 3. 绑定IP地址和端口号 if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { perror("bind失败"); close(server_socket); return -1; } printf("成功绑定到端口 %d\n", port); return server_socket; } int main(int argc, char *argv[]) { int server_socket; // 解析命令行参数 char *server_ip = NULL; int server_port = SERVER_PORT; if (argc >= 2) { server_port = atoi(argv[1]); if (server_port 65535) { printf("无效端口号: %s\n", argv[1]); exit(EXIT_FAILURE); } } if (argc >= 3) { server_ip = argv[2]; } // 创建和绑定服务器socket server_socket = create_and_bind_server(server_ip, server_port); if (server_socket == -1) { exit(EXIT_FAILURE); } // 4. 开始监听 if (listen(server_socket, BACKLOG) == -1) { perror("listen失败"); close(server_socket); exit(EXIT_FAILURE); } printf("服务器开始监听,等待客户端连接...\n"); printf("监听队列大小: %d (最多可同时等待 %d 个连接)\n", BACKLOG, BACKLOG); printf("服务器地址: %s:%d\n", server_ip ? server_ip : "0.0.0.0", server_port); // 5. 主循环:接受客户端连接 while (1) { printf("\n等待新的客户端连接...\n"); // 接受客户端连接 struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); int client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_len); if (client_socket == -1) { perror("accept失败"); continue; } printf("客户端连接成功: %s:%d (socket fd: %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), client_socket); // 创建结构体保存客户端信息 client_info_t* client_info = (client_info_t*)malloc(sizeof(client_info_t)); if (client_info == NULL) { perror("malloc失败"); close(client_socket); continue; } client_info->client_socket = client_socket; client_info->client_addr = client_addr; // 创建线程处理客户端连接 pthread_t tid; if (pthread_create(&tid, NULL, handle_client, client_info) != 0) { perror("pthread_create失败"); close(client_socket); free(client_info); } else { // 分离线程,在线程结束时自动回收资源 pthread_detach(tid); printf("为客户端 %s:%d 创建处理线程 %ld\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), tid); } } close(server_socket); return 0; }

得分 100
学习任务

cjozGV 的学生作业:

#include "stdio.h" #include "string.h" #include "stdlib.h" #define MAX 10 struct student{ char name[20]; int id; int age; }; typedef struct student datatype_t; typedef struct { datatype_t buf[MAX]; //定义数组记录班级学生每个学生的信息。 int n; //学生实际到来的个数。 }SeqList; //1.创建顺序表 SeqList* create_empty_seqlist(){ //1.声明指针并初始化为NULL SeqList *l = NULL; //2.在堆区分配内存 l = (SeqList*)malloc(sizeof(SeqList)); //3.检查malloc是否成功 if (NULL == l){ printf("malloc is fail!\n"); return NULL; } //4.初始化内存 memset(l,0, sizeof(SeqList)); //5.显示初始化关键成员 l->n = 0; return l; } //2.检查顺序表是否已满 int is_full_seqlist(SeqList *l){ //检查指针是否有效 if (NULL == l){ printf("error: seqlist_t pointer is NUlL.\n"); return 1; //返回已满阻止后续操作 } //判断是否已满 return (l->n >=MAX) ? 1:0; } //3.插入学生数据 void insert_data_seqlist(SeqList *l,datatype_t data){ if (NULL == l || is_full_seqlist(l)){ return; } l->buf[l->n++] = data; } //4.输出数据 void printf_data_seqlist(SeqList *l){ if(NULL == l){ return; } for (int i = 0; i < l->n; i++) { printf("Student %d:Name: %s, ID: %d, Age: %d\n", i+1,l->buf[i].name,l->buf[i].id,l->buf[i].age); } printf("----------------------------\n\n"); } int is_empty_seqlist(SeqList *l){ if (NULL == l){ return -1; } return (l->n == 0) ? 1:0; } int delete_data_seqlist(SeqList *l,int id){ if (NULL == l){ return -1; } if (is_empty_seqlist(l) == 1){ return -1; } int j = 0; int found = 0; //是否找到标记位 for (int i = 0; i n; i++) { if (l->buf[i].id != id){ l->buf[j] = l->buf[i]; j++; } else { found = 1; //找到匹配项 } } l->n = j; //更新元素个数 if (!found){ printf("error: Student (ID=%d) not found,deletion failed. \n",id); return -2; //未找到匹配项 } else { printf("Success: Delete student (ID: %d)\n",id); printf_data_seqlist(l); //打印删除后的学生信息 return 0; } } // 安全输入函数(避免 scanf 缓冲区问题) int safe_input(const char *prompt, char *buffer, int max_len) { printf("%s", prompt); if (fgets(buffer, max_len, stdin) == NULL) { return -1; // 输入失败 } // 去除换行符 buffer[strcspn(buffer, "\n")] = '\0'; return 0; } int main(){ SeqList* l = create_empty_seqlist(); if (NULL == l){ return -1; } char input_buf[100]; datatype_t data; printf("Enter student info (name id age), or 'q' to stop:\n"); //满了只取前十 while (!is_full_seqlist(l)){ printf("Student %d: ",l->n + 1); if (safe_input("Student %d: ",input_buf, sizeof(input_buf)) != 0){ continue; } //检查是否退出输入 if (strcmp(input_buf,"q") == 0){ break; } // 尝试解析输入 if (sscanf(input_buf, "%s %d %d", data.name, &data.id, &data.age) != 3) { printf("Input error! Please enter in format: name id age\n"); continue; } insert_data_seqlist(l, data); printf_data_seqlist(l); } // 删除测试 printf("\nEnter the ID of the student to delete: "); if (fgets(input_buf, sizeof(input_buf), stdin) == NULL) { printf("Invalid input!\n"); } else { int delete_id; if (sscanf(input_buf, "%d", &delete_id) != 1) { printf("Invalid ID input!\n"); } else { delete_data_seqlist(l, delete_id); } } free(l); l = NULL; return 0; }

得分 100
学习任务

史啦啦 的学生作业:

【图片】 #include #include #include #include #include /* See NOTES */ #include #include #include #define LISTEN_SZ 10 int main(int argc,char *argv[]) { int sfd,ret,cfd; struct sockaddr_in svr_addr,cli_addr; ssize_t sbytes = 0,rbytes = 0; char buffer[1024] = {0}; int length; int total_received; socklen_t len = sizeof(struct sockaddr_in); if (argc != 3){ fprintf(stderr,"usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } sfd = socket(AF_INET,SOCK_STREAM,0); if (sfd == -1){ perror("[ERROR] socket(): "); exit(EXIT_FAILURE); } bzero(&svr_addr,sizeof(struct sockaddr_in)); svr_addr.sin_family = AF_INET; svr_addr.sin_port = htons(atoi(argv[2])); svr_addr.sin_addr.s_addr = inet_addr(argv[1]); ret = bind(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); if (ret == -1){ perror("[ERROR] bind(): "); close(sfd); exit(EXIT_FAILURE); } ret = listen(sfd,LISTEN_SZ); if (ret == -1){ perror("[ERROR] listen(): "); close(sfd); exit(EXIT_FAILURE); } bzero(&cli_addr,sizeof(struct sockaddr_in)); cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len); if (cfd == -1){ perror("[ERROR] accept(): "); exit(EXIT_FAILURE); } printf("ip : %s,port : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port)); for(;;) { length = 0; total_received = 0; //接收数据的长度 rbytes = recv(cfd,&length,4,0); if(rbytes == -1) { perror("[ERROR] Failed to recv."); exit(EXIT_FAILURE); } for(;;) { rbytes = recv(cfd,buffer + total_received,length - total_received,0); if(rbytes == -1) { perror("[ERROR] Failed to recv"); exit(EXIT_FAILURE); } else if(rbytes == 0) { printf("The client has been shutdown.\n"); } else if(rbytes > 0) { total_received += rbytes; if(total_received == length) { break; } } } printf("buffer : %s\n",buffer); sleep(1);// 服务器间隔 1s 接收一次数据 } close(cfd); close(sfd); return 0; } #include #include #include #include #include #include #include /* See NOTES */ #include int main(int argc,char *argv[]) { int sfd,ret; ssize_t sbytes = 0,rbytes = 0; char sbuffer[1024] = "Hello,server"; int length = 0; char *pbuffer = NULL; struct sockaddr_in svr_addr; if (argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); return -1; } sfd = socket(AF_INET,SOCK_STREAM,0); if (sfd == -1){ perror("[ERROR] socket(): "); exit(EXIT_FAILURE); } bzero(&svr_addr,sizeof(svr_addr)); svr_addr.sin_family = AF_INET; svr_addr.sin_port = htons(atoi(argv[2])); svr_addr.sin_addr.s_addr = inet_addr(argv[1]); ret = connect(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr)); if (ret == -1){ perror("[ERROR] connect():"); exit(EXIT_FAILURE); } for(;;){ length = strlen(sbuffer); pbuffer = (char *)malloc(length + 4); memcpy(pbuffer,&length,4); memcpy(pbuffer + 4,sbuffer,length); sbytes = send(sfd,pbuffer,length + 4,0); if (sbytes == -1){ perror("[ERROR] send(): "); exit(EXIT_FAILURE); } usleep(100); } close(sfd); return 0; }

得分 100
学习任务

cjozGV 的学生作业:

#include "stdio.h" #include "string.h" #include "stdlib.h" #define MAX 10 struct student{ char name[20]; int id; int age; }; typedef struct student datatype_t; typedef struct { datatype_t buf[MAX]; //定义数组记录班级学生每个学生的信息。 int n; //学生实际到来的个数。 }SeqList; //1.创建顺序表 SeqList* create_empty_seqlist(){ //1.声明指针并初始化为NULL SeqList *l = NULL; //2.在堆区分配内存 l = (SeqList*)malloc(sizeof(SeqList)); //3.检查malloc是否成功 if (NULL == l){ printf("malloc is fail!\n"); return NULL; } //4.初始化内存 memset(l,0, sizeof(SeqList)); //5.显示初始化关键成员 l->n = 0; return l; } //2.检查顺序表是否已满 int is_full_seqlist(SeqList *l){ //检查指针是否有效 if (NULL == l){ printf("error: seqlist_t pointer is NUlL.\n"); return 1; //返回已满阻止后续操作 } //判断是否已满 return (l->n >=MAX) ? 1:0; } //3.插入学生数据 void insert_data_seqlist(SeqList *l,datatype_t data){ if (NULL == l || is_full_seqlist(l)){ return; } l->buf[l->n++] = data; } //4.输出数据 void printf_data_seqlist(SeqList *l){ if(NULL == l){ return; } for (int i = 0; i < l->n; i++) { printf("Student %d:Name: %s, ID: %d, Age: %d\n", i+1,l->buf[i].name,l->buf[i].id,l->buf[i].age); } printf("----------------------------\n\n"); } int main(){ SeqList* l = create_empty_seqlist(); if (NULL == l){ return -1; } datatype_t data; printf("please input %d number : ",MAX); //满了只取前十 while (!is_full_seqlist(l)){ printf("Student %d: ",l->n + 1); if (scanf("%s %d %d",data.name,&data.id,&data.age) != 3){ printf("Input error! Please enter name, id and age.\n"); //清除缓冲区 while (getchar() != '\n'); continue; } insert_data_seqlist(l,data); printf_data_seqlist(l); } // 释放内存(虽然这里顺序表是局部变量,但如果是动态分配的需手动释放) free(l); l = NULL; //避免悬空指针 return 0; }

得分 100
学习任务

慕尼黑0001808 的学生作业:

/* 练习 int a[2][3] = {10,20,30,40,50,60}; int (*p)[3] = a; 要求通过多种方式输出a数组中的数据 */ /* 个人总结: 指针与数组有很高的相似性(基本数据类型变量的指针,可以理解为一维一个元素的数组): 都是引用类型;* 都是用来取下级的0索引值;[] 都是用来取下级指定索引值;& 取本身的地址值;它们各级代表的数据类型相同;各级相同数据类型的偏移量是相同的。 数组取索引越界报错,指针取索引越界不会报错;它们的声明语法结构不同,数组声明:int a[3][2],指针:int (*p)[2];指针没有实际的数据,它需要依赖于变量来产生数,数组中有实际的数据。 */ #include int main() { int a[2][3] = {10,20,30,40,50,60}; int (*p)[3] = a; printf("a=%p\n",a); printf("a[0]=%p\n",a[0]); printf("&a=%p\n",&a); printf("&a[0]=%p\n",&a[0]); printf("*a=%p\n",*a); printf("**a=%d\n",**a); printf("========================================\n"); printf("sizeof(a)=%d\n",sizeof(a)); printf("sizeof(a[0])=%d\n",sizeof(a[0])); printf("sizeof(&a)=%d\n",sizeof(&a)); printf("sizeof(&a[0])=%d\n",sizeof(&a[0])); for(int i = 0;i < 2;i++) { for(int j = 0;j < 3;j++) { printf("==============================================\n"); printf("a[%d][%d]=%d\n",i,j,a[i][j]); printf("(*(a+%d))[%d]=%d\n",i,j,(*(a+i))[j]); printf("*(a[%d]+%d)=%d\n",i,j,*(a[i]+j)); printf("*(*(a+%d)+%d)=%d\n",i,j,*(*(a+i)+j)); printf("p[%d][%d]=%d\n",i,j,p[i][j]); printf("*(p[%d]+%d)=%d\n",i,j,*(p[i]+j)); printf("*(*(p+%d))+%d)=%d\n",i,j,*(*(p+i)+j)); } } return 0; }

得分 100
学习任务

史啦啦 的学生作业:

TCP 面向流的传输特性 TCP 协议本身是无消息边界的字节流传输协议。发送方的数据在传输层会被拆分成多个 TCP 段(Segment),接收方重组时仅保证字节顺序,不保留原始数据包的划分边界。 发送端优化机制 Nagle 算法:为减少小数据包的网络开销,发送端会合并多个小数据包(如多次 send() 调用)再发送。 缓冲区机制:应用层的数据先写入发送缓冲区,若缓冲区未满或未超时,可能延迟发送导致数据堆积。【图片】 #include #include #include #include #include #include #include #include int main(int argc,char *argv[]) { int sfd,ret; ssize_t sbytes = 0,rbytes = 0; char sbuffer[1024] = {0}; char rbuffer[1024] = {0}; struct sockaddr_in svr_addr; if (argc != 3){ fprintf(stderr,"Usage : %s < ip > < port >.\n",argv[0]); return -1; } sfd = socket(AF_INET,SOCK_STREAM,0); if (sfd == -1){ perror("[ERROR] socket(): "); exit(EXIT_FAILURE); } printf("sfd = %d\n",sfd); bzero(&svr_addr,sizeof(svr_addr)); svr_addr.sin_family = AF_INET; svr_addr.sin_port = htons(atoi(argv[2])); svr_addr.sin_addr.s_addr = inet_addr(argv[1]); ret = connect(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr)); if (ret == -1){ perror("[ERROR] connect():"); exit(EXIT_FAILURE); } for(;;){ strcpy(sbuffer,"hello,abcde"); sbytes = send (sfd,sbuffer,strlen(sbuffer),0); if (sbytes == -1){ perror("[ERROR] send(): "); exit(EXIT_FAILURE); } usleep(100); } close(sfd); return 0; } #include #include #include #include #include #include #include #include #define LISTEN_SZ 10 int main(int argc,char *argv[]) { if (argc != 3){ fprintf(stderr,"usage : %s < ip > < port >.\n",argv[0]); exit(EXIT_FAILURE); } int sfd,ret,cfd; struct sockaddr_in svr_addr,cli_addr; ssize_t sbytes,rbytes; char buffer[1024] = {0}; sfd = socket(AF_INET,SOCK_STREAM,0); if (sfd == -1){ perror("[ERROR] socket(): "); exit(EXIT_FAILURE); } bzero(&svr_addr,sizeof(struct sockaddr_in)); svr_addr.sin_family = AF_INET; svr_addr.sin_port = htons(atoi(argv[2])); svr_addr.sin_addr.s_addr = inet_addr(argv[1]); ret = bind(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); if (ret == -1){ perror("[ERROR] bind(): "); close(sfd); exit(EXIT_FAILURE); } ret = listen(sfd,LISTEN_SZ); if (ret == -1){ perror("[ERROR] listen(): "); close(sfd); exit(EXIT_FAILURE); } socklen_t len = sizeof(struct sockaddr_in); bzero(&cli_addr,sizeof(struct sockaddr)); cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len); if (cfd == -1){ perror("[ERROR] accept(): "); exit(EXIT_FAILURE); } printf("ip : %s,port : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port)); for(;;) { memset(buffer,sizeof(buffer),0); rbytes = recv(cfd,buffer,sizeof(buffer),0); if (rbytes == -1){ perror("recv(): "); exit(EXIT_FAILURE); }else if (rbytes == 0){ printf("The client is offline.\n"); exit(EXIT_FAILURE); }else if (rbytes > 0){ printf(" %s\n",buffer); } sleep(1);// 服务器间隔 1s 接收一次数据 } close(cfd); close(sfd); return 0; }

得分 100
学习任务

史啦啦 的学生作业:

【图片】 #include #include #include #include #include #include #include #include #define LISTEN_SZ 10 int main(int argc,char *argv[]) { if(argc != 3) { fprintf(stderr,"Usage : %s .\n",argv[0]); exit(EXIT_FAILURE); } int sfd,ret,cfd; struct sockaddr_in svr_addr,cli_addr; ssize_t sbytes,rbytes; char buffer[1024] = {0}; sfd = socket(AF_INET,SOCK_STREAM,0); if(sfd == -1) { perror("[ERROR] socket():"); exit(EXIT_FAILURE); } bzero(&svr_addr,sizeof(struct sockaddr_in)); svr_addr.sin_family = AF_INET; svr_addr.sin_port = htons(atoi(argv[2])); svr_addr.sin_addr.s_addr = inet_addr(argv[1]); ret = bind(sfd,(const struct sockaddr *)&svr_addr,sizeof(struct sockaddr_in)); if(ret == -1) { perror("[ERROR] bind():"); close(sfd); exit(EXIT_FAILURE); } ret = listen(sfd,LISTEN_SZ); if(ret == -1) { perror("[ERROR] listen():"); close(sfd); exit(EXIT_FAILURE); } socklen_t len = sizeof(struct sockaddr_in); bzero(&cli_addr,sizeof(struct sockaddr)); cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len); if(cfd == -1) { perror("[ERROR] accept():"); exit(EXIT_FAILURE); } printf("ip : %s,port : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port)); //接收客户端的数据 while(1) { memset(buffer,0,sizeof(buffer)); rbytes = recv(cfd,buffer,sizeof(buffer),0); if(rbytes == -1) { perror("[ERROR] recv():"); exit(EXIT_FAILURE); } else if(rbytes == 0) { printf("The client is offline.\n"); exit(EXIT_FAILURE); } else if(rbytes > 0) { //接收到客户端数据回传给客户端 sbytes = send(cfd,buffer,sizeof(buffer),0); if(sbytes == -1) { perror("[ERROR] send():"); exit(EXIT_FAILURE); } } if(strncmp(buffer,"quit",4) == 0) { break; } } return 0; }

得分 100
学习任务

Hee_cryLQ0 的学生作业:

seqlist.h #ifndef __SEQLIST__ #define __SEQLIST__ #include #include #include #define MAX 10 typedef struct student { char name[20]; int id; int age; }datatype_t; typedef struct { datatype_t buf[MAX]; //buf[10]:顺序表中有10个学生 int n; }seqlist_t; seqlist_t *create_empty_seqlist(); int is_full_seqlist(seqlist_t *list); void insert_data_seqlist(seqlist_t *list, datatype_t data); void printf_data_seqlist(seqlist_t *list); #endif //__SEQLIST__ seqlist.c #include "seqlist.h" /*创建一个空的顺序表*/ seqlist_t *create_empty_seqlist() { seqlist_t *list = NULL; //list本身是局部变量 list = (seqlist_t *)malloc(sizeof(seqlist_t));//而list保存的地址在堆区 if(NULL == list) { printf("malloc seqlist failed!\n"); return NULL; } memset(list, 0, sizeof(seqlist_t)); list->n = 0; return list; } /*检查顺序表是否已经存满数据MAX=10*/ int is_full_seqlist(seqlist_t *list) { return list->n == MAX ? 1 : 0; } /*向顺序表中插入学生信息,传入学生对象data*/ void insert_data_seqlist(seqlist_t *list, datatype_t data) { strcpy(list->buf[list->n].name, data.name);//数组名是数组首地址,不能对数组名进行=赋值,所以需要使用strcpy list->buf[list->n].id = data.id; list->buf[list->n].age = data.age; list->n = list->n + 1; //list->n++; return ; } /*打印顺序表中的学生信息*/ void printf_data_seqlist(seqlist_t *list) { printf("name\tid\tage\n"); for(int i = 0; i < list->n; i++) { printf("%s\t%d\t%d\n",list->buf[i].name, list->buf[i].id, list->buf[i].age); } return ; } main.c #include "seqlist.h" int main() { seqlist_t *list = NULL; list = create_empty_seqlist();//创建一个空表 datatype_t data; //创建学生对象 printf("请输入学生的信息,最多输入%d个。\n", MAX); while(!is_full_seqlist(list)) { scanf("%s%d%d", data.name, &data.id, &data.age); insert_data_seqlist(list, data); } printf_data_seqlist(list); free(list); list = NULL; return 0; }

微信客服

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

帮助反馈 APP下载

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

公众号

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