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

作业社区

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

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

wgf1209 的学生作业:

tcp_server.h #ifndef __SERVER_H__ #define __SERVER_H__ #include #include #include #include #include #include #include #include #include /* @Author: wjhu8 @Time: 2024-10-30 21:29:32 @name: tcp_server.h */ #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" #define BOUNDARY "cyg-boundary" #define WEB_DIR "www" typedef enum { A_SNAPSHOT, //快照--截图 A_STREAM, //流---视频 A_FILE, //文件 } answer_t; //HTTP请求 typedef struct { answer_t type; char *parm; } request_t; //1.创建 tcp server socket extern int create_tcp_server_socket(const char *ip, const char *port); //2.等待并接受客户端连接,返回新的连接套接字文件描述符。 extern int accept_client_connect(int sockfd, struct sockaddr_in *cli_addr); //3.显示连接客服端的地址信息 extern void show_tcp_network_address(struct sockaddr_in *sockaddr); extern void *client_thread(void *arg); extern int analyse_http_request(const char *buf, request_t *req); extern void send_file(int sockfd, char *file_path); extern void send_stream(int sockfd); extern void send_snapshot(int sockfd); #endif //__SERVER_H__ tcp_server.c #include #include #include #include #include #include #include #include #include #include "../head/debug.h" #include "../head/tcp_server.h" #include "../head/global.h" /* @Author: wjhu8 @Time: 2024-10-30 21:29:32 @name: tcp_server.c */ //自定义宏 ----> 监听队列的长度 #define BACKLOG 10 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"} }; global_t global; //初始化套接字 int init_tcp(const char *ipstr, unsigned short port, int backlog) { int sfd; //1.创建套接字 sfd = socket(AF_INET, SOCK_STREAM, 0); if (sfd == -1) { DEBUG_INFO("[ERROR] Failed to socket: %s\n", strerror(errno)); return -1; } int on = 1; if (0 > setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { DEBUG_INFO("[ERROR] Failed to setsockopt: %s\n", strerror(errno)); return -1; } struct sockaddr_in addr = { // 初始化服务器地址结构体对象 .sin_family = AF_INET, //协议族----> AF_INTE .sin_port = htons(port), //端口 .sin_addr.s_addr = htons(INADDR_ANY), //IP地址 .sin_zero={0}, }; //2.绑定服务端本身的ip和port到socket if (0 > bind(sfd, (const struct sockaddr *) &addr, sizeof(addr))) { DEBUG_INFO("[ERROR] Failed to bind: %s\n", strerror(errno)); return -1; } listen(sfd, backlog); printf("Listen sfd %d port %d\n", sfd, port); printf("server ip is %s\n", inet_ntoa(addr.sin_addr)); return sfd; } //函数作用:创建 tcp server socket int create_tcp_server_socket(const char *ip, const char *port) { int sfd, ret; struct sockaddr_in svr_addr; //1.创建套接字 sfd = socket(AF_INET, SOCK_STREAM, 0); if (sfd == -1) { DEBUG_INFO("[ERROR] Failed to socket: %s\n", strerror(errno)); return -1; } //将 svr_addr 结构体变量所占用的内存区域全部设置为零 bzero(&svr_addr, sizeof(struct sockaddr_in)); // 初始化服务器地址结构体对象 svr_addr.sin_family = AF_INET; //协议族----> AF_INTE svr_addr.sin_port = htons(atoi(port)); //端口 svr_addr.sin_addr.s_addr = inet_addr(ip); //IP地址 //2.绑定服务端本身的ip和port到socket ret = bind(sfd, (const struct sockaddr *) &svr_addr, sizeof(struct sockaddr_in)); if (ret == -1) { DEBUG_INFO("[ERROR] Failed to bind: %s\n", strerror(errno)); return -1; } //3.将套接字设置为监听状态并创建监听队列 ret = listen(sfd, BACKLOG); //BACKLOG(监听队列的长度) 10 if (ret == -1) { DEBUG_INFO("[ERROR] Failed to listen: %s\n", strerror(errno)); return -1; } return sfd; } //函数作用:等待并接受客户端连接,返回新的连接套接字文件描述符。 int accept_client_connect(int sockfd, struct sockaddr_in *cli_addr) { int cfd; socklen_t len = sizeof(struct sockaddr_in); //4.与客户端进行三次握手并建立连接 并返回新的套接字文件描述符 cfd = accept(sockfd, (struct sockaddr *) cli_addr, &len); if (cfd == -1) { DEBUG_INFO("[ERROR] Failed to accept: %s\n", strerror(errno)); return -1; } return cfd; } //显示连接客服端的地址信息 void show_tcp_network_address(struct sockaddr_in *sockaddr) { //打印IP地址和端口信息 printf("ip : %s port : %d\n", inet_ntoa(sockaddr->sin_addr), ntohs(sockaddr->sin_port)); } void *client_thread(void *arg) { char buf[1024] = {0}; int rws = (int) arg; //初始化buff,将buf设置为零 bzero(buf, sizeof(buf)); //接收客户端的数据 if (0 > recv(rws, buf, sizeof(buf) - 1, 0)) { DEBUG_INFO("[ERROR] Failed to recv: %s\n", strerror(errno)); goto end; } request_t request = { .type = 0, .parm = NULL, //这里需要开辟空间存放http数据. }; if (analyse_http_request(buf, &request) < 0) { DEBUG_INFO("[ERROR] Failed to analyse_http_request: %s\n", strerror(errno)); goto end; } switch (request.type) { case A_FILE: send_file(rws, request.parm); break; case A_SNAPSHOT: send_snapshot(rws); break; case A_STREAM: send_stream(rws); break; } end: close(rws); if (NULL != request.parm) { free(request.parm); } return NULL; } int analyse_http_request(const char *buf, request_t *req) { char *url = strstr(buf, "GET /"); if (NULL == url) { printf("Http request error!\n"); return -1; } url += strlen("GET /"); char arr[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-1234567890"; int len = MIN(MAX(strspn(url, arr), 0), 100); req->parm = (char *) malloc(len + 1); memset(req->parm, 0, len + 1); memcpy(req->parm, url, len); printf("req->parm : %s.\n", req->parm); req->type = A_FILE; return 0; } void send_stream(int sockfd) { int length; char buf[BUFFER_SIZE]; printf("send_stream(%d)\n", sockfd); sprintf(buf, "HTTP/1.1 200 OK\r\n" \ STD_HEADER \ "Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n" \ "\r\n" \ "--" BOUNDARY "\r\n"); if (send(sockfd, buf, strlen(buf), 0) < 0) { perror("send_stream() fail to send http head"); return; } char *frame = NULL; while (global.capture) //how to stop? { pthread_mutex_lock(&global.update_lock); pthread_cond_wait(&global.update_cond, &global.update_lock); length = global.length; frame = (char *) malloc(global.length); memcpy(frame, global.start, global.length); pthread_mutex_unlock(&global.update_lock); /* print the individual mimetype and the length * sending the content-length fixes random stream disruption observed * with firefox */ sprintf(buf, "Content-Type: image/jpeg\r\n" \ "Content-Length: %d\r\n" \ "\r\n", length); if (0 > send(sockfd, buf, strlen(buf), 0)) { perror("send_stream() Fail to send http header"); break; } if (0 > send(sockfd, frame, length, 0)) { perror("send_stream() Fail to send camera frame"); break; } sprintf(buf, "\r\n--" BOUNDARY "\r\n"); if (0 > send(sockfd, buf, strlen(buf), 0)) { break; } free(frame); usleep(100); } free(frame); return; } void send_file(int sockfd, char *file_path) { int n, fd; char buf[1024] = {0}; char *extension, *mimetype = NULL; if (file_path == NULL || strlen(file_path) == 0) file_path = "index.html"; /* find file-extension */ if (NULL == (extension = strstr(file_path, "."))) { // send_error(fd, 400, "No file extension found"); return; } /* determine mime-type */ for (int i = 0; i < sizeof(mimetypes) / sizeof(mimetypes[0]); ++i) { if (0 == strcmp(mimetypes[i].dot_extension, extension)) { mimetype = (char *) mimetypes[i].mimetype; break; } } if (NULL == mimetype) { return; } //打开文件 sprintf(buf, "%s/%s", WEB_DIR, file_path); if ((fd = open(buf, O_RDONLY)) < 0) { fprintf(stderr, "Fail to open %s : %s.\n", buf, strerror(errno)); //send error to webbrowser return; } // 添加http头. memset(buf, 0, sizeof(buf)); sprintf(buf, "HTTP/1.0 200 OK\r\n" \ "Content-type: %s\r\n" \ STD_HEADER \ "\r\n", mimetype); //注意这里会多出个空行. // 发送http头信息和网页文件数据. n = strlen(buf); //发送http头信息和网页文件数据. do { if (0 > send(sockfd, buf, n, 0)) { perror("send_file() Fail to send file contain"); } } while (n = read(fd, buf, sizeof(buf))); return; } void send_snapshot(int sockfd) { int length; char *frame; char buf[BUFFER_SIZE]; printf("send_snapshot(%d)\n", sockfd); pthread_mutex_lock(&global.update_lock); pthread_cond_wait(&global.update_cond, &global.update_lock); //获得视频数据 length = global.length; frame = (char *) malloc(global.length); memcpy(frame, global.start, global.length); pthread_mutex_unlock(&global.update_lock); //添加http头 memset(buf, 0, sizeof(buf)); sprintf(buf, "HTTP/1.0 200 OK\r\n" \ "Content-type: image/jpeg\r\n" \ STD_HEADER \ "\r\n"); //发送http头 if (0 > send(sockfd, buf, strlen(buf), 0)) { printf("send_snapshot() send http head failure\n"); free(frame); return; } //发送视频数据 if (0 > send(sockfd, frame, length, 0)) { printf("send_snapshot() send frame failure\n"); } free(frame); return; } main.c #include #include #include #include #include #include #include "head/debug.h" #include "head/camera.h" #include "head/tcp_server.h" #include "head/global.h" /* @Author: wjhu8 @Time: 24-10-29 下午8:57 @name: main.c */ int main(void) { #if 0 int cmd_fd = init_camera("/dev/video0"); if (-1 == cmd_fd) { perror("init_camera failure!\n"); return -1; } if (-1 == init_mmap(cmd_fd)) { perror("init_mmap failure!\n"); return -1; } start_camera(cmd_fd); //9.监测fd的读事件,并在可读时读取数据 struct timeval tv; tv.tv_sec = 20; tv.tv_usec = 0; fd_set fds; FD_ZERO(&fds); FD_SET(cmd_fd, &fds); int r = select(cmd_fd + 1, &fds, NULL, NULL, &tv); if (0 == r) { printf("no frame for read!\n"); return 0; } else { if (FD_ISSET(cmd_fd, &fds)) { if (-1 == read_camera(cmd_fd)) { printf("read_camera() failure!\n"); return -1; } } } #endif int sfd, cfd, ret; pthread_t tid; struct sockaddr_in addr; //1.创建 tcp server socket sfd = create_tcp_server_socket("192.168.197.15", "8080"); while (1) { //2.用于与客户端建立连接 cfd = accept_client_connect(sfd, &addr); //3.显示连接客服端的地址信息 show_tcp_network_address(&addr); //4.子进程执行任务 int ret = pthread_create(&tid, NULL, client_thread, (void *) cfd); if (0 != ret) { DEBUG_INFO("[ERROR] Failed to pthread_create: %s\n", strerror(errno)); exit(EXIT_FAILURE); } pthread_detach(tid); printf("loop again\n"); } return 0; } 【图片】 【图片】

得分 100
学习任务

weixin_慕哥3021856 的学生作业:

#include #include #include #include #include #include #include #include #include void send_data(int sockfd, struct sockaddr_in *addr, int len) { int fd, n = 0; ssize_t rbytes; char buffer[1024] = {0}; char *filepath = "./log.txt"; fd = open(filepath, O_RDONLY); if (fd == -1) { fprintf(stderr, "Open failed.\n"); exit(EXIT_FAILURE); } while ((rbytes = read(fd, buffer, sizeof(buffer)-1)) > 0) { n = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)addr, len); if (n < 0) { perror("Fail to send data.\n"); exit(EXIT_FAILURE); } memset(buffer, 0, sizeof(buffer)); } printf("Data send completed.\n"); close(fd); return ; } void write_file() { int fd; ssize_t wbytes; char *filename = "log.txt"; char buf[1024]; fd = open(filename, O_WRONLY|O_CREAT); if (fd == -1) { perror("open failed.\n"); exit(EXIT_FAILURE); } printf("Input words to file: "); while (1) { memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); // buf[strlen(buf)-1] = '\0'; if (strncmp(buf, "quit", 4) == 0) break; wbytes = write(fd, buf, strlen(buf)+1); if (wbytes == -1) { perror("[ERROR] write()"); close(fd); exit(EXIT_FAILURE); } } close(fd); printf("File %s creat successfully.\n", filename); return ; } int main(int argc, const char *argv[]) { int sockfd = 0; struct sockaddr_in peer_addr; if (argc != 3) { fprintf(stderr, "Usage: %s ip port\n", argv[0]); exit(EXIT_FAILURE); } write_file(); socklen_t len = sizeof(peer_addr); // 通过socket创建文件描述符 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("[ERROR] socket()"); exit(EXIT_FAILURE); } // 填充服务器的ip地址和端口号 memset(&peer_addr, 0, sizeof(peer_addr)); peer_addr.sin_family = AF_INET; peer_addr.sin_port = htons(atoi(argv[2])); peer_addr.sin_addr.s_addr = inet_addr(argv[1]); send_data(sockfd, &peer_addr, len); close(sockfd); return 0; } 【图片】

微信客服

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

帮助反馈 APP下载

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

公众号

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