freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

基于mjpeg-streamer的遠(yuǎn)程視頻監(jiān)控系統(tǒng)-資料下載頁(yè)

2025-06-27 18:10本頁(yè)面
  

【正文】 memcpy(out+pos, buf, sizein)。 pos += sizein。/*復(fù)制幀起始標(biāo)志0xffco之前的數(shù)據(jù)*/ memcpy(out+pos, dht_data, sizeof(dht_data))。 pos += sizeof(dht_data)。/*插入赫夫曼表*/ memcpy(out+pos, ptcur, size sizein)。 pos += sizesizein。 return pos。} 6 視頻傳輸與網(wǎng)絡(luò)視頻服務(wù)器視頻的傳送需要遵照一定的協(xié)議才能正確實(shí)現(xiàn)數(shù)據(jù)發(fā)送,視頻傳輸部分則對(duì)此作了詳細(xì)的說(shuō)明,包括網(wǎng)絡(luò)通信協(xié)議TCP/IP,以及Linux操作系統(tǒng)中的網(wǎng)絡(luò)編程即Socket編程。瀏覽器向服務(wù)器請(qǐng)求數(shù)據(jù)以及向?yàn)g覽器發(fā)送數(shù)據(jù)都需也有固定的格式要求,如要有文件類型說(shuō)明,瀏覽器才能正確區(qū)分不同類型的文件,從而正確顯示出文本,畫面等豐富多彩的內(nèi)容。這些在HTTP中都有明確的規(guī)定。網(wǎng)絡(luò)視頻服務(wù)器部分就對(duì)網(wǎng)絡(luò)服務(wù)器的原理和實(shí)現(xiàn)作了詳細(xì)說(shuō)明,包括并發(fā)服務(wù)器及其所用到的多線程編程,客戶端響應(yīng)線程,還包括目標(biāo)板和瀏覽器間交互的應(yīng)用層協(xié)議HTTP。 視頻傳輸 TCP/IP協(xié)議簇基礎(chǔ)雖然TCP/IP從名字上看,只包含了兩個(gè)協(xié)議,但實(shí)際上,TCP/IP是一個(gè)龐大的協(xié)議族,它包括了各個(gè)層次上的眾多協(xié)議。TCP/IP可以劃分為四層:應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、網(wǎng)絡(luò)接口層,是OSI七層模型的簡(jiǎn)化。本設(shè)計(jì)應(yīng)用層使用的是HTTP協(xié)議,傳輸層使用的是TCP協(xié)議。 Linux Socket編程簡(jiǎn)介(1) Socket定義在Linux中的網(wǎng)絡(luò)編程是通過(guò)Socket接口來(lái)進(jìn)行的。它是一種特殊的I/O接口,也是一種常用的進(jìn)程之間的通信機(jī)制,通過(guò)它不僅能實(shí)現(xiàn)本地機(jī)器上的進(jìn)程之間的通信,而且通過(guò)網(wǎng)絡(luò)能夠?qū)崿F(xiàn)在不同機(jī)器上不同進(jìn)程之間進(jìn)行通信。Socket信息保存在sockaddr_in結(jié)構(gòu)中。在Linux中所有設(shè)備都看做文件,Socket也不例外,創(chuàng)建Socket后,會(huì)返回描文件描述符,隨后的連接、數(shù)據(jù)收發(fā)等操作都是通過(guò)該文件描述符操作的。也就是說(shuō)向網(wǎng)絡(luò)上的主機(jī)收發(fā)數(shù)據(jù),就像是對(duì)一個(gè)文件進(jìn)行讀寫操作一樣。(2) Socket編程Socket編程的基本函數(shù)有socket、bind、listen、accept、send、sendto、recv以及recvfrom等,其中根據(jù)是在客戶端還是在服務(wù)器端,以及使用的是TCP協(xié)議還是UDP協(xié)議,函數(shù)的調(diào)用流程都會(huì)有所區(qū)別,本系統(tǒng)使用TCP協(xié)議作為傳輸層協(xié)議。TCP協(xié)議socket編程流程如圖5。首先服務(wù)器端和客戶端都必須創(chuàng)建Socket,它是通信的基礎(chǔ)。服務(wù)器綁定了IP和端口等之后,執(zhí)行監(jiān)聽(tīng),接著調(diào)用accept等待客戶端發(fā)送連接請(qǐng)求。此時(shí),客戶端可以跳過(guò)綁定,直接向服務(wù)器發(fā)送連接請(qǐng)求connect,雙方便建立通信連接。若連接成功,雙方就可以實(shí)現(xiàn)收發(fā)數(shù)據(jù)。通信結(jié)束后雙方都要關(guān)閉Socket,并釋放Socket結(jié)構(gòu)。圖5 TCP協(xié)議socket編程流程圖 網(wǎng)絡(luò)服務(wù)器 多線程編程簡(jiǎn)介(1) 線程的定義線程是進(jìn)程中的一個(gè)獨(dú)立的控制流,由環(huán)境(包括寄存器和程序計(jì)數(shù)器)和一系列要執(zhí)行的指令組成。它是進(jìn)程內(nèi)一條獨(dú)立的運(yùn)行路線,是處理器調(diào)度的最小單元,又稱為輕量級(jí)進(jìn)程。(2) 多線程相對(duì)于多進(jìn)程的優(yōu)勢(shì)進(jìn)程是系統(tǒng)中程序執(zhí)行和資源分配的基本單位。每個(gè)進(jìn)程都擁有自己的數(shù)據(jù)段、代碼段和堆棧段,這就造成了進(jìn)程在進(jìn)行切換等操作時(shí)都需要有比較復(fù)雜的上下文切換等動(dòng)作。為了進(jìn)一步減少處理機(jī)的空轉(zhuǎn)時(shí)間,支持多處理器以及減少上下文切換開(kāi)銷,在進(jìn)程的基礎(chǔ)上演化出了線程。線程可以對(duì)進(jìn)程的內(nèi)存空間和資源進(jìn)行訪問(wèn),并與同一進(jìn)程中的其他線程共享數(shù)據(jù)區(qū)。因此,線程的上下文切換的開(kāi)銷相比進(jìn)程小要很多。(3) 進(jìn)程與線程的關(guān)系一個(gè)進(jìn)程可以有多個(gè)線程,也就是有多個(gè)線程控制表及堆棧寄存器,但卻共享一個(gè)用戶地址空間。要注意的是,由于線程共享了進(jìn)程的資源和地址空間,因此,任何線程對(duì)系統(tǒng)資源的操作都會(huì)給其他線程帶來(lái)影響。由此可知,多線程中的同步是非常重要的問(wèn)題。在多線程系統(tǒng)中,進(jìn)程與進(jìn)程的關(guān)系如圖6所示。圖6 進(jìn)程與進(jìn)程的關(guān)系 HTTP簡(jiǎn)介(1) HTTP定義超文本傳送協(xié)議 (HTTP)是一種通信協(xié)議,屬于應(yīng)用層中面向?qū)ο蟮膮f(xié)議。它允許將超文本標(biāo)記語(yǔ)言 (HTML)文檔從WEB服務(wù)器傳送到WEB瀏覽器。HTML是一種用于創(chuàng)建文檔的標(biāo)記語(yǔ)言,這些文檔包含相關(guān)信息的鏈接。可以實(shí)現(xiàn)單擊一個(gè)鏈接來(lái)訪問(wèn)其它文檔、圖像或多媒體對(duì)象,并獲得關(guān)于鏈接項(xiàng)的附加信息?,F(xiàn)在WWW中使用的是版本是HTTP/。(2) HTTP請(qǐng)求要獲得一個(gè)WEB文檔,瀏覽器首先與服務(wù)器80端口建立一條連接,然后使用HTTP發(fā)送一個(gè)請(qǐng)求。其請(qǐng)求和應(yīng)答是一行或多行文本,結(jié)束標(biāo)志是一個(gè)換行符(回車、換行)。如果請(qǐng)求成功,信息(文本文檔、圖像數(shù)據(jù))就沿該連接發(fā)送,直至傳送完成斷開(kāi)連接。HTTP中的命令稱為方法(method),其中GET方法用于獲取文檔,POST方法用來(lái)請(qǐng)求服務(wù)器接收指定文檔作為可執(zhí)行的信息。HTTP請(qǐng)求包括:請(qǐng)求行,請(qǐng)求頭,有時(shí)還有請(qǐng)求主體。請(qǐng)求最簡(jiǎn)單的形式是由一個(gè)文本行構(gòu)成,包括大寫的關(guān)鍵詞GET、文件名、協(xié)議標(biāo)識(shí)符和回車換行符。例如,GET/ HTTP/CRLF。本設(shè)計(jì)的主頁(yè)文件的HTML代碼見(jiàn)附錄二。(3) HTTP響應(yīng)HTTP應(yīng)答也包括三個(gè)部分:狀態(tài)行,響應(yīng)頭,應(yīng)答主體。以下是一個(gè)簡(jiǎn)單的HTTP響應(yīng)實(shí)例:HTTP/ 200 OKContentType: text/filenameChenjinhui狀態(tài)行:TTP/,200表示請(qǐng)求成功。響應(yīng)頭:ContentType: text/filename,表示服務(wù)器將要發(fā)送的文件的類型為文本,文件名為filename。主體:空行標(biāo)記報(bào)文頭結(jié)束,之后的是主體部分,內(nèi)容為Chenjinhui。此外,本系統(tǒng)中服務(wù)器要不斷向?yàn)g覽器發(fā)送圖像數(shù)據(jù),但是,通常一個(gè)HTTP響應(yīng)只能發(fā)送一個(gè)數(shù)據(jù)塊,因此,為了避免不斷地發(fā)送請(qǐng)求,響應(yīng),采用了服務(wù)器推送技術(shù)。其實(shí)現(xiàn)很簡(jiǎn)單只需要將contenttype指定為:contenttype:multipart/xmixedreplace。boundary=BOUNDARY。 并發(fā)服務(wù)器線程實(shí)現(xiàn)(1) server_thread線程流程分析server_thread線程流程見(jiàn)圖2。首先定義兩個(gè)Socket結(jié)構(gòu),addr和client_addr,分別存儲(chǔ)服務(wù)器的信息和與其連接的客戶端信息。之后按照?qǐng)D5所示的TCP協(xié)議的Socket編程流程,完成綁定,監(jiān)聽(tīng),等待連接請(qǐng)求。一旦有客戶端連接請(qǐng)求,馬上又創(chuàng)建一個(gè)新的線程,用來(lái)專門處理該連接請(qǐng)求,從而實(shí)現(xiàn)了服務(wù)器可以一直監(jiān)聽(tīng)客戶端請(qǐng)求,即構(gòu)成了并發(fā)服務(wù)器。(2) 并發(fā)服務(wù)器線程函數(shù)server_thread的實(shí)現(xiàn)代碼void *server_thread( void *arg ) { struct sockaddr_in addr, client_addr。//服務(wù)器和客戶端Socket pthread_t client。//客戶端線程ID socklen_t addr_len = sizeof(struct sockaddr_in)。 context *pcontext = arg。/*包括所用的套接字sd,本身的線程ID */ pglobal = pcontextpglobal。 …… /* (TCP)套接字(Socket)*/ pcontextsd = socket(PF_INET, SOCK_STREAM, 0)。 if (setsockopt(pcontextsd, SOL_SOCKET, SO_REUSEADDR, amp。on, sizeof(on)) 0) {/*SO_REUSEADDR:允許重復(fù)綁定本地地址和端口*/ perror(setsockopt(SO_REUSEADDR) failed)。 exit(EXIT_FAILURE)。 } /* 2. 配置端口,IP */ memset(amp。addr, 0, sizeof(addr))。 = AF_INET。/*IPV4*/ = pcontext。 /*端口*/ = htonl(INADDR_ANY)。/*使服務(wù)器監(jiān)聽(tīng)任意IP*/ /* 3. 將端口,IP與套接字綁定 */ if ( bind(pcontextsd, (struct sockaddr*)amp。addr, sizeof(addr)) != 0 ) { perror(bind)。 OPRINT(%s(): bind(%d) failed, __FUNCTION__, htons(pcontext))。 closelog()。 exit(EXIT_FAILURE)。 } /* 4. 監(jiān)聽(tīng),最大允許請(qǐng)求數(shù)為10 */ if ( listen(pcontextsd, 10) != 0 ) { fprintf(stderr, listen failed\n)。 exit(EXIT_FAILURE)。 } while ( !pglobalstop ) { cfd *pcfd = malloc(sizeof(cfd))。 /* 新客戶端請(qǐng)求,都要申請(qǐng)本結(jié)構(gòu),客戶端線程會(huì)先復(fù)制再釋放 */ if (pcfd == NULL) { fprintf(stderr, failed to allocate (a very small amount of) memory\n)。 exit(EXIT_FAILURE)。 } /* 5. 阻塞方式等待客戶端連接*/ pcfdfd = accept(pcontextsd, (struct sockaddr *)amp。client_addr, amp。addr_len)。 pcfdpc = pcontext。 /*6. 創(chuàng)建客戶端線程*/ if( pthread_create(amp。client, NULL, amp。client_thread, pcfd) != 0 ) { close(pcfdfd)。 free(pcfd)。 continue。 } pthread_detach(client)。 } …… return NULL。} HTTP請(qǐng)求響應(yīng)線程實(shí)現(xiàn)(1) 客戶端響應(yīng)線程client_thread的流程分析client_thread的流程見(jiàn)圖2的client_thread部分。首先判斷是否開(kāi)啟了用戶身份驗(yàn)證功能,若不為空則開(kāi)啟了用戶身份驗(yàn)證。,若不同則返回錯(cuò)誤信息,若相同則通過(guò)驗(yàn)證。之后是發(fā)送HTTP響應(yīng)頭,使用了服務(wù)器推送技術(shù)。設(shè)置好了HTTP響應(yīng)頭,就可以不斷地發(fā)送圖片信息,而且每一張新發(fā)送的圖片信息都會(huì)覆蓋上一張圖片,從而在瀏覽器上看到的就是動(dòng)態(tài)的視頻。發(fā)送圖片部分也是由全局變量pglobalstop控制的循環(huán)體。首先調(diào)用阻塞等待函數(shù)pthread_cond_wait,等待圖像采集線程cam_thread發(fā)送的線程廣播pthread_cond_broadcast。但是當(dāng)有多個(gè)客戶端時(shí),該線程不一定馬上就能夠響應(yīng),因?yàn)槎鄠€(gè)客戶端線程處于競(jìng)爭(zhēng)關(guān)系,他必須等待優(yōu)先級(jí)比它高的客戶端線程服務(wù)完,才能從等待狀態(tài)喚醒,進(jìn)入執(zhí)行狀態(tài)。喚醒后,首先它要告訴服務(wù)器發(fā)送的是什么類型的數(shù)據(jù),數(shù)據(jù)大小等,例如ContentType: image/jpeg就表示發(fā)送的是JPEG格式的圖像數(shù)據(jù),然后才是完整的JPEG文件。發(fā)送完JPEG文件后,還要插入分隔符BOUNDARY,用來(lái)告知瀏覽器可以刷新屏幕了。(2) 客戶端響應(yīng)線程client_thread的實(shí)現(xiàn)代碼void *client_thread( void *arg ) { int t。 …… /*用戶登錄密碼檢查*/ if ( != NULL ) { if ( == NULL || strcmp(, ) != 0 ) { send_error(, 401, username and password do not match to configuration)。 …… return NULL。 } } send_snapshot()。/*新連接的客戶端socket描述符*/ ……}(3) 發(fā)送JPEG數(shù)據(jù)函數(shù)send_streamvoid send_stream(int fd) { unsigned char *frame=NULL, *tmp=NULL。 int frame_size=0, max_frame_size=0。 char buffer[BUFFER_SIZE] = {0}。 /*發(fā)送響應(yīng)頭*/ sprintf(buffer, HTTP/ 200 OK\r\n \ STD_HEADER \ ContentType: multipart/xmixedreplace。boundary= BOUNDARY \r\n \ \r\n \ BOUNDARY \r\n)。 if ( write(fd, buffer, strlen(buffer)) 0 ) { free(f
點(diǎn)擊復(fù)制文檔內(nèi)容
環(huán)評(píng)公示相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1