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

作业社区

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

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

邓文兵 的学生作业:

//服务器接收客户端请求,使用多线程方式处理多个客户端上传文件请求 //测试服务器通信 void server_thread_upload(int argc,char *argv[]) { //先判断读入参数是否符合格式要求 if(argc!=3) { fprintf(stderr,"Usage: %s \n",argv[0]); exit(EXIT_FAILURE); } //创建服务器专门用于监听客户端请求文件描述符与专用通信文件描述符 int sockfd,new_fd; //定义线程id,fork线程处理多个客户端的上传文件请求 pthread_t tid; int ret; //初始化成功连接客户端配置结构体 struct sockaddr_in client_info{}; socklen_t len=sizeof(struct sockaddr_in); //获取服务端套接字文件描述符 sockfd=create_TCPSERVER_socket(argv[1],atoi(argv[2])); if(sockfd==-1) { exit(EXIT_FAILURE); } while (true) { //每次接收到新客户端之前需要清空客户端配置信息结构体 memset(&client_info,0,sizeof(sockaddr_in)); //服务端绑定并监听端口接收客户端请求 new_fd=accept_client(sockfd,&client_info,&len); if(new_fd==-1) { exit(EXIT_FAILURE); } //三次握手成功建立连接打印客户端配置信息 print_tcp_network_address(&client_info); //开始与客户端进行收发通信 ret=pthread_create(&tid,nullptr,do_task,(void*)&new_fd); if(ret!=0) { DEBUG_INFO("pthread_create failed...\n"); exit(EXIT_FAILURE); } pthread_detach(tid); } //服务端是有两个文件描述符需要关闭,一个用于监听连接,一个用于与客户端进行通信 close(sockfd); } //测试客户端连接服务器以后上传文件功能 void client_upload(int argc,char *argv[]) { if(argc!=4) { fprintf(stderr,"Usage: %s \n",argv[0]); exit(EXIT_FAILURE); } int sockfd; //创建客户端socket套接字文件描述符,并于服务器进行连接 sockfd=create_TCPCLIENT_socket(argv[1],atoi(argv[2])); //处理连接失败异常 if(sockfd==-1) { exit(EXIT_FAILURE); } //与服务器建立连接以后,调用客户端上传文件接口,将指定的pathname文件上传至服务器 client_upload_file(argv[3],sockfd); close(sockfd); }

得分 100
学习任务

邓文兵 的学生作业:

//客户端发送文件头-读取本地文件-将读取到的内容通过TCP协议发送给服务器 //客户端发送完文件协议头后,会获取文件的总长度,接下来上传文件至服务器保存,返回上传文件大小 int client_upload_file(const char *filename,int new_fd) { int file_size=0;//获取文件的总长度 int fd;//文件打开描述符 //定义缓冲区用于读写文件 char buffer[1024]{0}; //定义文件读取,写入记录字节数 size_t rbytes=0,wbytes=0; size_t total_write=0; //客户端发送文件协议头给服务器 file_size=send_protocol_head(filename,new_fd); if(file_size==-1) { return -1;//标识客户端发送文件协议头失败 } //客户端打开本地文件读入内存,随后将文件数据发送给服务器 fd=open(filename,O_RDONLY); if(fd==-1) { DEBUG_INFO("file open failed...\n"); return -1; } //开始循环读取本地文件,直至读完整个文件,同步将读到的内容往服务器上传 while(true) { //读文件,读到的内容至buffer中 rbytes=read(fd,buffer,sizeof(buffer)); //读文件异常 if(rbytes==-1) { DEBUG_INFO("read failed...\n"); return -1; }else if(rbytes==0) { break; } //将读取到的数据上传给服务器 wbytes=send_package(new_fd,buffer,rbytes); //若读写数据不一致,那么返回错误 if(wbytes!=rbytes) { DEBUG_INFO("send_package failed...\n"); } total_write+=rbytes; } //关闭文件描述符,并返回成功上传的字节数 close(fd); return static_cast(total_write); }

得分 100
学习任务

weixin_慕哥3021856 的学生作业:

#include #include #include #include #include #include #include #include #include #include #include #define LOGIN_SUCCESS 1 #define LOGIN_FAILURE 0 typedef struct{ const char *ip; unsigned char flag; struct sockaddr_in *peer_addr; }thread_type; int init_socket(const char *ip, const char *port) { int sockfd = 0; struct sockaddr_in saddr; // server addr socklen_t len = sizeof(saddr); sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket failed.\n"); exit(EXIT_FAILURE); } // 填充服务器自身的IP和端口号 memset(&saddr, 0 , sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = inet_addr(ip); saddr.sin_port = htons(atoi(port)); if (bind(sockfd, (struct sockaddr *)&saddr, len) < 0) { perror("bind failed.\n"); exit(EXIT_FAILURE); } printf("Wait to receive data...\n"); return sockfd; } void printf_client_info(struct sockaddr_in *addr, char *buffer) { printf("--------------------\n"); printf("Recv from ip: %s\n", inet_ntoa(addr->sin_addr)); printf("Recv from port: %d\n", ntohs(addr->sin_port)); printf("Recv data: %s\n", buffer); } void recv_data(int sockfd) { int n = 0; char buf[1024] = {0}; struct sockaddr_in client_addr; socklen_t len = sizeof(client_addr); while (1) { memset(buf, 0, sizeof(buf)); n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&client_addr, &len); if (n < 0) { perror("[ERROR] recvfrom()"); exit(EXIT_FAILURE); } if (strncmp(buf, "quit", 4) == 0) { printf("\nBye!\n"); break; } printf_client_info(&client_addr, buf); } close(sockfd); return ; } void *message_thread(void *arg) { // 服务端在密钥正确时回复的信息 thread_type *packet = (thread_type *)arg; const char *ip = packet->ip; unsigned char login_flag = packet->flag; struct sockaddr_in *addr = packet->peer_addr; // 创建新的套接字和端口用于通信 int new_sockfd = init_socket(ip, "0"); sendto(new_sockfd, &login_flag, sizeof(login_flag), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in)); // 接收数据 recv_data(new_sockfd); pthread_exit(NULL); } void user_login(const char *ip, const char *port) { int n = 0; int sockfd, ptsockfd; // pthread new sockfd char buf[32] = {0}; unsigned char login_flag; struct sockaddr_in caddr; // client addr socklen_t len = sizeof(caddr); pthread_t tid; thread_type packet; // get socket sockfd = init_socket(ip, port); while (1) { memset(buf, 0, sizeof(buf)); n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&caddr, &len); if (n < 0) { perror("[ERROR] recvfrom()"); exit(EXIT_FAILURE); } printf("Your key is %s\n", buf); login_flag = (strncmp(buf, "root", 4) == 0)? LOGIN_SUCCESS: LOGIN_FAILURE; // 密钥正确 if (login_flag == LOGIN_SUCCESS) { packet.ip = ip; packet.flag = login_flag; packet.peer_addr = &caddr; printf("login successfully!\n"); // 创建子线程,子线程准备接收当前用户的数据,主线程负责接收用户的密钥 int err = pthread_create(&tid, NULL, message_thread, (void *)&packet); if (err != 0) { fprintf(stderr, "[ERROR] pthread_create(): %s\n", strerror(err)); exit(EXIT_FAILURE); } } else { // 给客户端回复登录失败 sendto(sockfd, &login_flag, sizeof(login_flag), 0, (struct sockaddr *)&caddr, len); } // 待系统自动回收线程,把线程设置为分离式 pthread_detach(tid); } return ; } int main(int argc, const char *argv[]) { if (argc != 3) { fprintf(stderr, "Usage: %s ip port\n", argv[0]); exit(EXIT_FAILURE); } // 验证密钥,执行用户登录 user_login(argv[1], argv[2]); return 0; } 【图片】

得分 100
学习任务

邓文兵 的学生作业:

//服务器接收文件数据并写入到本地文件中,返回值为接收到的文件大小 //传入的三个参数,第一个为服务器专用的读写文件描述符,期望写入的本地文件名,文件的目标大小(来源于解析获取到的文件协议头中的文件长度) int recv_file_data(int new_fd,const char *filename,size_t target_size) { //打开文件返回文件描述符,后续往这里面写入读到的数据 int fd; //初始化当前读取与写入的字节数 size_t rbytes=0,wbytes=0; size_t file_size=0; //初始化缓冲区 char buffer[1024]; memset(buffer,0,sizeof(buffer)); fd=open(filename,O_WRONLY | O_CREAT | O_TRUNC,0644); //处理打开异常 if(fd==-1) { DEBUG_INFO("file open failed\n"); return -1; } //循环调用封装好的服务器接收数据包接口开始接收数据 while (true) { rbytes=recv_package(new_fd,buffer,sizeof(buffer)); if(rbytes==-1) { //读取数据失败 DEBUG_INFO("recv_package failed...\n"); return -1; }else if(rbytes==0) { //当读取到0时,标识当前客户端已断开连接 DEBUG_INFO("client has been shut down...\n"); break; }else if(rbytes>0){ //将读取到的字节数写入到本地文件中 wbytes=write(fd,buffer,rbytes); //处理文件写入本地文件发生异常 if(wbytes==-1) { DEBUG_INFO("write failed...\n"); return -1; } file_size+=rbytes;//累计当前已经写入到本地文件的字节数 if(file_size==target_size) { //完成读取整个文件的数据量 break; } } } close(fd); //直接返回一个文件大小 return file_size; }

微信客服

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

帮助反馈 APP下载

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

公众号

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