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

作业社区

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

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

大禹123 的学生作业:

debug.h #ifndef _DEBUG_H_ #define _DEBUG_H_ /* __FILE__: 输出文件名 __FUNCTION__: 输出函数名 __LINE__: 输出行号 */ // 使用 snprintf 代替 sprintf,防止缓冲区溢出 #define DEBUG_INFO(fmt, ...) do { \ char buf[1024]; \ snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \ fprintf(stderr, "[%s, %s, %d] : %s\n", __FILE__, __FUNCTION__, __LINE__, buf); \ } while (0) #endif // _DEBUG_H_ server.h #ifndef __SERVER_H__ #define __SERVER_H__ #include /* See NOTES */ #include #include #include #include #include #include #include #include #include #include "global.h" #include #include #include #include #include #define BACKBLOG 10 typedef enum { A_SNAPSHOT, A_STREAM, A_FILE } answer_t; typedef struct { answer_t type; char *parm; /* data */ }request_t; #define STD_HEADER "Connection: close\r\n" \ "Server: MJPG-Streamer/0.2\r\n" \ "Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n" \ "Pragma: no-cache\r\n" \ "Expires: Mon, 3 Jan 2013 12:34:56 GMT\r\n" extern int init_tcp(const char *ip, const unsigned short port, int backlog); extern void *client_thread(void *arg); extern int analyse_http_request(const char *buf, request_t *req); extern void send_file(int sockfd, char *filename); #endif global.h #ifndef __GLOBAL_H_ #define __GLOBAL_H_ #define MAX(a, b) ((a) > (b)) ? (a) : (b) #define MIN(a, b) ((a) < (b)) ? (a) : (b) #endif server.c #include "server.h" #include "debug.h" #define WEB_DIR "./www/" static const struct { const char *dot_extension; const char *mimetype; } mimetypes[] = { {".html", "text/html"}, {".htm", "text/html"}, {".css", "text/css"}, {".js", "text/javascript"}, {".txt", "text/plain"}, {".jpg", "image/jpeg"}, {".jpeg", "image/jpeg"}, {".png", "image/png"}, {".gif", "image/gif"}, {".ico", "image/x-icon"}, {".swf", "application/x-shockwave-flash"}, {".cab", "application/x-shockwave-flash"}, {".jar", "application/java-archive"}}; int init_tcp(const char *ip, const unsigned short port, int backlog) { int sfd, on = 1; // 創建套接字 sfd = socket(AF_INET, SOCK_STREAM, 0); if (sfd == -1) { DEBUG_INFO("[ERROR] socket():%s\n", strerror(errno)); return -1; } if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { DEBUG_INFO("[ERROR] setsockopt():%s\n", strerror(errno)); } struct sockaddr_in saddr; memset(&saddr, 0, sizeof(struct sockaddr_in)); saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = inet_addr(ip); if (bind(sfd, (const struct sockaddr *)&saddr, sizeof(struct sockaddr_in)) < 0) { DEBUG_INFO("[ERROR] bind():%s\n", strerror(errno)); return -1; } listen(sfd, backlog); printf("listen fd %d\n", sfd); printf("server ip is %s port %d\n", inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); return sfd; } void *client_thread(void *arg) { int rbytes; int cfd = (int)arg; char buf[1024] = {0}; // 线程内栈空间大小有限,不能占太大内存 rbytes = recv(cfd, buf, sizeof(buf) - 1, 0); if (rbytes < 0) { DEBUG_INFO("[ERROR]:recv() failure%s\n", strerror(errno)); pthread_exit(NULL); } request_t req; if (analyse_http_request(buf, &req) < 0) { DEBUG_INFO("[ERROR]:analyse_http_request() failure\n"); pthread_exit(NULL); } switch (req.type) { case A_FILE: send_file(cfd, req.parm); break; } close(cfd); pthread_exit(NULL); } int analyse_http_request(const char *buf, request_t *req) { // 如果找到字符串,则返回指向字符串的第一个字符的地址 char *url = strstr(buf, "GET /"); if (NULL == url) { DEBUG_INFO("[ERROR]:http request fail\n"); return -1; } url += strlen("GET /"); // 有效的url字母序列 char arr[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-1234567890"; int len = MIN(MAX(strspn(url, arr), 0), 100); req->parm = (char *)calloc(1, len + 1); memcpy(req->parm, url, len); printf("req->parm:%s\n", req->parm); req->type = A_FILE; return 0; } void send_file(int sockfd, char *filename) { int bytes, fd, i; char buf[1024] = {0}; char *externsion = NULL, *mimetype = NULL; if (filename == NULL || strlen(filename) == 0) { filename = "index.html"; } // 定位到扩展名 if (NULL == (externsion = strstr(filename, "."))) { return; } for (int i = 0; i < sizeof(mimetypes) / sizeof(mimetypes[0]); i++) { if (0 == strcmp(mimetypes[i].dot_extension, externsion)) { externsion = (char *)mimetypes[i].dot_extension; mimetype = (char *)mimetypes[i].mimetype; break; } } if (NULL == externsion) { return; } // 将格式化的数据写入一个字符串缓冲区 sprintf(buf, "%s%s", WEB_DIR, filename); printf("pathname:%s", buf); if ((fd = open(buf, O_RDONLY)) < 0) { DEBUG_INFO("[ERROR]:open() fail%s\n", strerror(errno)); return; } memset(buf, 0, sizeof(buf)); sprintf(buf, "HTTP/1.0 200 OK\r\n" "Content-type: %s\r\n" STD_HEADER "\r\n", mimetype); // 注意这里会多出个空行. bytes = strlen(buf); do { if (0 > send(sockfd, buf, bytes, 0)) { DEBUG_INFO("[ERROR]:send() fail%s\n", strerror(errno)); } memset(buf, 0, sizeof(buf)); } while ((bytes = read(fd, buf, sizeof(buf))) > 0); close(fd); return; } main.c #include "debug.h" #include "server.h" #include #include #include #include #include int main(int argc, char const *argv[]) { #if 0 int cam_fd; cam_fd = init_camera("/dev/video0"); if (-1 == cam_fd) { DEBUG_INFO("[ERROR]:init_camera() failure"); return -1; } cam_fd = init_mmap(cam_fd); if (-1 == cam_fd) { DEBUG_INFO("[ERROR]:init_camera() failure"); return -1; } cam_fd = start_camera(cam_fd); if (-1 == cam_fd) { DEBUG_INFO("[ERROR]:init_camera() failure"); return -1; } cam_fd = wait_camera(cam_fd); if (-1 == cam_fd) { DEBUG_INFO("[ERROR]:wait_camera() failure"); return -1; } #endif struct sockaddr_in c_addr; int cfd; // 用于和客户端通信的套接字 int ret; socklen_t addr_len = sizeof(struct sockaddr_in); pthread_t tid; int sfd = init_tcp("127.0.0.1", 8080, BACKBLOG); memset(&c_addr, 0, addr_len); while (1) { printf("addr_len = %d\n", addr_len); cfd = accept(sfd, (struct sockaddr *)&c_addr, &addr_len); printf("cfd = %d\n", cfd); if (-1 == cfd) { DEBUG_INFO("[ERROR]:accept() failure%s\n",strerror(errno)); continue; } printf("cfd = %d\n", cfd); ret = pthread_create(&tid, NULL, client_thread, (void *)cfd); //此处不能传地址,因为循环的速度有可能大于线程创建的速度 if (ret != 0) { DEBUG_INFO("[ERROR]:pthread_create() failure%s\n",strerror(errno)); continue; } pthread_detach(tid); printf("loop again\n"); } return 0; } result【图片】

得分 0
学习任务

胡汉三66 的学生作业:

#include #include #include #include #include #include #include #include //创建两个子进程A与B,父进程分别给两个子进程发送消息,消息类型为100与200 //父进程从键盘循环接收数据,发送给子进程.输入quit则结束 #define PATHNAME "." #define PROID 168 #define MSG_TYPE_A 100 #define MSG_TYPE_B 200 struct msgbuf{ long mtype; char mtext[64]; }; int main(void) { pid_t fpid_a,fpid_b;//子进程A,子进程B key_t key;//key值 int msqid;//消息队列ID int ret; char buffer[64]; int *ws_a,*ws_b;//子进程退出状态 struct msgbuf msg_a;//创建消息结构体a struct msgbuf msg_b;//创建消息结构体b msg_a.mtype = 100;//消息结构体a的 消息类型为 100 msg_b.mtype = 200;//消息结构体b的 消息类型为 200 for(;;) { printf("Message queues write data >");//消息队列写入数据 fgets(buffer,sizeof(buffer),stdin);//从标准输入 读取数据 保存在字符数组buffer中 buffer[strlen(buffer) - 1] = '\0';// 将'\n'替换为'\0' if (strncmp(buffer,"quit",4) == 0)//如果输入"quit",则退出程度 { printf("Goodbye!\n"); break; } key = ftok(PATHNAME,PROID);//创建KEY值 if (key == -1) { perror("[ERROR] ftok():\n"); exit(EXIT_FAILURE); } msqid = msgget(key,IPC_CREAT | 0666);//创建消息队列 if (msqid == -1) { perror("[ERROR] msgget():\n"); exit(EXIT_FAILURE); } printf("msg id : %d\n",msqid);//打印消息队列ID fpid_a = fork();//创建子进程A if (fpid_a == -1) { perror("[ERROE] fork();\n"); exit(EXIT_FAILURE); }else if (fpid_a == 0)//子进程A { struct msgbuf msg_a_rcv;//子进程A 消息接收结构体 ssize_t rbytes_a; printf("Child A < %d > start.\n",getpid()); rbytes_a = msgrcv(msqid,(void *)&msg_a_rcv,64,MSG_TYPE_A,0); if(rbytes_a == -1) { perror("[ERROR] msgrcv () :\n"); exit(EXIT_FAILURE); } printf("Child A Message mtype: %ld\n",msg_a_rcv.mtype); printf("Child A Message mtext: %s\n",msg_a_rcv.mtext); exit(EXIT_SUCCESS); }else if (fpid_a > 0)//父进程 { strcpy(msg_a.mtext,buffer);//将数组buffer中的数据 拷贝到 消息结构体 msg_a 的消息内容 mtext 中 ret = msgsnd(msqid,(const void *)&msg_a,strlen(msg_a.mtext) + 1,0); if (-1 == ret) { perror("[ERROR] msgsnd_a ():\n"); exit(EXIT_FAILURE); } fpid_b = fork();//创建子进程B if (fpid_b == -1) { perror("[ERROE] fork();\n"); exit(EXIT_FAILURE); }else if (fpid_b == 0)//子进程B { struct msgbuf msg_b_rcv;//子进程B 消息接收结构体 ssize_t rbytes_b; printf("Child B < %d > start.\n",getpid()); rbytes_b = msgrcv(msqid,(void *)&msg_b_rcv,64,MSG_TYPE_B,0); if(rbytes_b == -1) { perror("[ERROR] msgrcv_b () :\n"); exit(EXIT_FAILURE); } printf("Child B Message mtype: %ld\n",msg_b_rcv.mtype); printf("Child B Message mtext: %s\n",msg_b_rcv.mtext); exit(EXIT_SUCCESS); }else if (fpid_b > 0)//父进程 { strcpy(msg_b.mtext,buffer);//将数组buffer中的数据 拷贝到 消息结构体 msg_a 的消息内容 mtext 中 ret = msgsnd(msqid,(const void *)&msg_b,strlen(msg_b.mtext) + 1,0); if (-1 == ret) { perror("[ERROR] msgsnd_b ():\n"); exit(EXIT_FAILURE); } //等待两个子进程退出,然后释放 创建子进程时产生的资源 wait(NULL); wait(NULL); ret = msgctl(msqid,IPC_RMID,NULL);//删除消息队列 if (ret == -1) { perror("[ERROR] msgctl () :\n"); exit(EXIT_FAILURE); } } } } return 0; } 【图片】

微信客服

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

帮助反馈 APP下载

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

公众号

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