📄 webserver.c
字号:
/******************************************************************************** # # # A Simple tool to monitor somwhere through a web camera # # Copyright (C) 2008 Zang Bin(OWEN) # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; version 2 of the License. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # ********************************************************************************/#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <errno.h>#include "webserver.h"#include "input_plugin.h"#define DEBUG 1#define MAX_SIZE 262144globals pglobal;const unsigned short port = 8003; // Default server port numberchar *error_return = "<HTML>\n<BODY>404 File not found\n</BODY>\n</HTML>";char ret_buf[MAX_SIZE];void send_snapshot(int client){ unsigned char *frame = NULL; int frame_size = 0; if ((frame = (unsigned char *) malloc(MAX_SIZE)) == NULL) { fprintf(stderr, "not enough memory\n"); exit(EXIT_FAILURE); } /* wait for a fresh frame */ pthread_cond_wait(&(pglobal.db_update), &(pglobal.db)); /* read buffer */ frame_size = pglobal.size; memcpy(frame, pglobal.buf, frame_size); if (DEBUG) printf("got frame (size: %d kB)\n", frame_size / 1024); pthread_mutex_unlock(&pglobal.db); /* send to socket */ send(client, frame, frame_size, 0); free(frame);}void send_stream(int client){ unsigned char *frame = NULL; int frame_size = 0; char buffer[512] = { 0 }; if (DEBUG) printf("preparing header\n"); if ((frame = (unsigned char *) malloc(MAX_SIZE)) == NULL) { fprintf(stderr, "not enough memory\n"); exit(EXIT_FAILURE); } sprintf(buffer, "HTTP/1.0 200 OK\r\n" "Content-Type: multipart/x-mixed-replace;boundary= boundarydonotcross \r\n" "\r\n" "-- boundarydonotcross \n"); if (write(client, buffer, strlen(buffer)) < 0) { return; } if (DEBUG) printf("Headers send, sending stream now\n"); while (!pglobal.stop) { /* wait for fresh frames */ pthread_cond_wait(&pglobal.db_update, &pglobal.db); /* read buffer */ frame_size = pglobal.size; memcpy(frame, pglobal.buf, frame_size); if (DEBUG) printf("got frame (size: %d kB)\n", pglobal.size / 1024); if (send(client, pglobal.buf, pglobal.size, 0) < 0) break; pthread_mutex_unlock(&pglobal.db); }}void send_file(char *filename, int client){ int nread; FILE *fp; // fetch file: if ((fp = fopen(filename, "r")) == NULL) send(client, error_return, sizeof(error_return), 0); nread = fread(ret_buf, 1, MAX_SIZE, fp); if (DEBUG) printf("%d bytes read from file %s\n", nread, filename); if (nread == 0) { fclose(fp); send(client, error_return, sizeof(error_return), 0); } ret_buf[nread] = '\0'; fclose(fp); send(client, ret_buf, nread, 0);}int main(int argc, char *argv[]){ int serverSocket, connectSocket; char *cbuf; struct sockaddr_in serverAddr; struct sockaddr_in clientAddr; int fileSize, totalSent, bytesSent; pthread_t dev_thread; // pthread_t client_thread_t; int index = 0; //pthread_create(&dev_thread, NULL, input_run, NULL); printf("device start..."); if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Invalid socket\n"); exit(1); } serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(port); serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&(serverAddr.sin_zero), 0, 8); printf("Binding server socket to port %d\n", port); if (bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(struct sockaddr)) == -1) { printf("Bad bind\n"); exit(1); } listen(serverSocket, 10); // allow 10 queued requests printf("Accepting connections ...\n"); while (1) { socklen_t clientAddrSize = sizeof(struct sockaddr_in); if ((connectSocket = accept(serverSocket, (struct sockaddr *) &clientAddr, &clientAddrSize)) == -1) { printf("Bad accept\n"); exit(1); } //------------ if (pthread_create (&client_thread_t, NULL, client_thread, (void *) connectSocket)) perror("client_thread create error"); index++; printf("%d", index); } return 0;}void *client_thread(void *arg){ int connectSocket = (int) arg; char recvBuffer[4001]; int nread; char *cp, *cp2; if ((nread = recv(connectSocket, recvBuffer, 4000, 0)) == -1) exit(EXIT_FAILURE); if (recvBuffer[nread - 1] != '\n') exit(EXIT_FAILURE); recvBuffer[nread] = '\0'; if (DEBUG) { printf("Received from client: %s", recvBuffer); } cp = recvBuffer + 5; cp2 = strstr(cp, " HTTP"); if (cp2 != NULL) *cp2 = '\0'; if (DEBUG) printf("request: %s\n", cp); if (strcmp(cp, "") == 0) { sprintf(cp, "html/index.html"); send_file(cp, connectSocket); } else if (strstr(cp, "?action=snapshot") != NULL) { send_snapshot(connectSocket); } else if (strstr(cp, "?action=stream") != NULL) { send_stream(connectSocket); } else { char file[20]; sprintf(file, "html/%s", cp); send_file(file, connectSocket); } if (DEBUG) printf("Connection closed by client.\n"); close(connectSocket); pthread_exit(NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -