PC端通过isapi协议抓拍摄像头图片

说明:
1、isapi协议类似于http协议
2、通过isapi协议抓拍图片要经过这几个步骤
2.1、先创建socket,再连接服务器(也就是摄像机)connect
2.2、发送没有认证得请求send
2.3、服务器响应401,根据www-Authenticate返回来得属性值,生成摘要认证
2.4、再次发送带有认证得请求
2.5、服务器响应400。

**以下是实现得代码:
tcpclient.cpp

#ifndef WINDOWS
#define WINDOWS
#endif#ifdef WINDOWS
#include<WINSOCK2.H>
#include <WS2tcpip.h>
#else
#include <iconv.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#endif #ifdef WINDOWS
#pragma warning(disable:4996)
#pragma comment(lib, "WS2_32.lib")
#endif #include <errno.h>
#include <string.h>
#include "httpauth.h"char * url = (char*)"/ISAPI/Streaming/channels/101/picture";
char * cmd = (char*)"GET";
const char * username_t = "admin";
const char * passworld_t = "znrt8899";
const char * realm_t = "DS-2CD7A27EWD-IZS";
const char * nonce_t = "4d6a46444d7a5a464e3045364e5449355a546c695932553d";
const char * nc_t = "00000001";
const char * cnonce_t = "8887920ea7e5c1c8";
const char * response_t = "5a9aa58fb654e667ad9d8e8adaa336df";
const char * qop_t = "auth";FILE *fp = NULL;void initialization();
int main(int argc, char * argv[])
{int sd, ret;char rcv_buf[1024*1024] = {0};struct sockaddr_in ser_sockaddr;int cnt = 0;httpauth_t auth;initialization();while (1){//返回套接字描述符sd = socket(AF_INET, SOCK_STREAM, 0); //创建socket连接 选择IPV4的TCP协议数据包if (sd == -1){printf("TCP套接字创建失败\r\n");}//设置sockaddr_in结构体中相关参数ser_sockaddr.sin_family = AF_INET;                                        //地址族 IPV4ser_sockaddr.sin_port = htons(80);                                        //设置为要连接的服务器的端口号(short数据转化为网络数据)ser_sockaddr.sin_addr.s_addr = inet_addr("192.168.0.200");                //设置服务器的IP地址(字符串转化为整形)ret = connect(sd, (struct sockaddr *)&ser_sockaddr, sizeof(ser_sockaddr));//连接服务器if (ret == -1){printf("连接服务器失败\r\n");return -1;}printf("连接服务器成功\r\n");//struct timeval timeout = { 10, 0 };if (cnt == 0) {httpauth_set_auth(&auth, username_t, passworld_t, realm_t, nonce_t, nc_t, cnonce_t, response_t, qop_t);request(sd, &auth, 0);recv(sd, rcv_buf, 1024, 0);printf("%s\r\n", rcv_buf);prase_response(rcv_buf, &auth);}else {int rs = 1;int buflen = 0;int rev_pos = 0;int len;int jpeg_len;httpauth_get_response(&auth, cmd, url);memset(rcv_buf, 0, 1024);request(sd, &auth, 1);Sleep(1);len = sizeof(rcv_buf);while (rs){buflen = recv(sd, &rcv_buf[rev_pos], len - rev_pos, 0);printf("%s\r\n", rcv_buf);printf("buflen is %d \r\n", buflen);printf("rcv_buf is %d \r\n", sizeof(rcv_buf));if (buflen < 0){// 由于是非阻塞的模式,所以当buflen为EAGAIN时,表示当前缓冲区已无数据可读// 在这里就当作是该次事件已处理if (errno == EINTR)continue;elsebreak;}else if (buflen == 0){// 这里表示对端的socket已正常关闭.char *begin = NULL;begin = strstr(rcv_buf, "Content-Length:");jpeg_len = atoi(begin + 15);begin = strstr(rcv_buf, "\r\n\r\n");fp = fopen("./pic.JPEG", "wb");fwrite(begin + 4, jpeg_len, 1, fp);}if (buflen != 0)rs = 1;elsers = 0;rev_pos += buflen;}return 0;}closesocket(sd);cnt++;}return 0;
}
void initialization() {//初始化套接字库WORD w_req = MAKEWORD(2, 2);//版本号WSADATA wsadata;int err;err = WSAStartup(w_req, &wsadata);if (err != 0) {printf("初始化套接字库失败!");}else {printf("初始化套接字库成功!");}//检测版本号if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {printf("套接字库版本号不符!");WSACleanup();}else {printf("套接字库版本正确!");}}

httpauth.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define ISspace(x) isspace((int)(x))
#define USERLEN 33
#define REALMLEN 64
#define QOPLEN   32
typedef struct httpauth_t {char username[USERLEN], password[USERLEN];char qop[QOPLEN], realm[QOPLEN], nc[QOPLEN];char cnonce[REALMLEN], response[REALMLEN], nonce[REALMLEN];
}httpauth_t;void to_hex(char *in, int len, unsigned char *out);
void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest);int httpauth_set_auth(httpauth_t *auth, const char* username, const char* password, const char* realm, const char* nonce, const char* nc, const char* cnonce, const char* response, const char* qop);
int httpauth_get_response(httpauth_t *auth, char *cmd, char *url);
void request(int socket_fd, httpauth_t *auth, int flag);
int prase_response(char * response_buf, httpauth_t *auth);

httpauth.cpp

#include "httpauth.h"#ifndef WINDOWS
#define WINDOWS
#endif#ifdef WINDOWS
#include<WINSOCK2.H>
#include <WS2tcpip.h>
#else
#include <iconv.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>#endif // WINDOWS#ifdef WINDOWS
#pragma warning(disable:4996)
#pragma comment(lib, "WS2_32.lib")
#endif // WINDOWS
const uint32_t k[64] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };// r specifies the per-round shift amounts
const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
};// leftrotate function definition
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))void to_bytes(uint32_t val, uint8_t *bytes)
{bytes[0] = (uint8_t)val;bytes[1] = (uint8_t)(val >> 8);bytes[2] = (uint8_t)(val >> 16);bytes[3] = (uint8_t)(val >> 24);
}uint32_t to_int32(const uint8_t *bytes)
{return (uint32_t)bytes[0]| ((uint32_t)bytes[1] << 8)| ((uint32_t)bytes[2] << 16)| ((uint32_t)bytes[3] << 24);
}void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest) {// These vars will contain the hashuint32_t h0, h1, h2, h3;// Message (to prepare)uint8_t *msg = NULL;size_t new_len, offset;uint32_t w[16];uint32_t a, b, c, d, i, f, g, temp;// Initialize variables - simple count in nibbles:h0 = 0x67452301;h1 = 0xefcdab89;h2 = 0x98badcfe;h3 = 0x10325476;//Pre-processing://append "1" bit to message    //append "0" bits until message length in bits � 448 (mod 512)//append length mod (2^64) to messagefor (new_len = initial_len + 1; new_len % (512 / 8) != 448 / 8; new_len++);msg = (uint8_t*)malloc(new_len + 8);memcpy(msg, initial_msg, initial_len);msg[initial_len] = 0x80; // append the "1" bit; most significant bit is "first"for (offset = initial_len + 1; offset < new_len; offset++)msg[offset] = 0; // append "0" bits// append the len in bits at the end of the buffer.to_bytes(initial_len * 8, msg + new_len);// initial_len>>29 == initial_len*8>>32, but avoids overflow.to_bytes(initial_len >> 29, msg + new_len + 4);// Process the message in successive 512-bit chunks://for each 512-bit chunk of message:for (offset = 0; offset < new_len; offset += (512 / 8)) {// break chunk into sixteen 32-bit words w[j], 0 � j � 15for (i = 0; i < 16; i++)w[i] = to_int32(msg + offset + i * 4);// Initialize hash value for this chunk:a = h0;b = h1;c = h2;d = h3;// Main loop:for (i = 0; i < 64; i++) {if (i < 16) {f = (b & c) | ((~b) & d);g = i;}else if (i < 32) {f = (d & b) | ((~d) & c);g = (5 * i + 1) % 16;}else if (i < 48) {f = b ^ c ^ d;g = (3 * i + 5) % 16;}else {f = c ^ (b | (~d));g = (7 * i) % 16;}temp = d;d = c;c = b;b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);a = temp;}// Add this chunk's hash to result so far:h0 += a;h1 += b;h2 += c;h3 += d;}// cleanupfree(msg);//var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)to_bytes(h0, digest);to_bytes(h1, digest + 4);to_bytes(h2, digest + 8);to_bytes(h3, digest + 12);
}void to_hex(char *in, int len, unsigned char *out)
{static char const hex[] = "0123456789abcdef";unsigned i;memset(out, 0, len * 2 + 1);for (i = 0;i < len;i++){out[2 * i] = hex[(in[i] >> 4) & 0x0F];out[2 * i + 1] = hex[(in[i] & 0x0F)];//printf("%d#%2.2x##%2.2x###%2.2x\n",i,in[i],out[2*i],out[2*i+1]);}
}int httpauth_set_auth(httpauth_t *auth, const char* username, const char* password, const char* realm, const char* nonce, const char* nc, const char* cnonce, const char* response, const char* qop)
{strcpy(auth->username, username);strcpy(auth->password, password);strcpy(auth->realm, realm);strcpy(auth->nonce, nonce);strcpy(auth->nc, nc);strcpy(auth->cnonce, cnonce);strcpy(auth->response, response);strcpy(auth->qop, qop);return 0;
}int httpauth_get_response(httpauth_t *auth, char *cmd, char *url)
{uint8_t strH1[512], strH2[512];uint8_t md5_h1[33], md5_h2[33];uint8_t result[16], result2[16];size_t len;//md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<url>))memset(strH1, 0, 512);sprintf((char*)strH1, "%s:%s:%s", auth->username, auth->realm, auth->password);len = strlen((char*)strH1);md5(strH1, len, result);to_hex((char*)result, 16, md5_h1);memset(strH2, 0, 512);sprintf((char*)strH2, "%s:%s", cmd, url);len = strlen((char*)strH2);md5(strH2, len, result2);to_hex((char*)result2, 16, md5_h2);memset(strH1, 0, 512);sprintf((char*)strH1, "%s:%s:%s:%s:%s:%s", md5_h1, auth->nonce, auth->nc, auth->cnonce, auth->qop, md5_h2);//    printf("response %s\r\n",strH1);len = strlen((char*)strH1);md5(strH1, len, result);to_hex((char*)result, 16, (unsigned char *)auth->response);//  printf("response = %s\r\n",auth->response);return 0;
}/**********************************************************************/
/* send a no authentication request */
/**********************************************************************/
void request(int socket_fd, httpauth_t *auth, int flag)
{char buf[2048];int pos = 0;pos = sprintf(&buf[pos], "GET /ISAPI/Streaming/channels/101/picture HTTP/1.1\r\n");pos += sprintf(&buf[pos], "Host:192.168.0.200\r\n");pos += sprintf(&buf[pos], "Connection: keep-alive\r\n");pos += sprintf(&buf[pos], "Cache-Control: max-age=0\r\n");if (1 == flag){pos += sprintf(&buf[pos], "Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"/ISAPI/Streaming/channels/101/picture\", response=\"%s\", qop=auth, nc=00000001, cnonce=\"%s\"\r\n", auth->username, auth->realm, auth->nonce, auth->response, auth->cnonce);}pos += sprintf(&buf[pos], "Upgrade-Insecure-Requests: 1\r\n");pos += sprintf(&buf[pos], "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36\r\n");pos += sprintf(&buf[pos], "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n");pos += sprintf(&buf[pos], "Accept-Encoding: gzip, deflate, sdch\r\n");pos += sprintf(&buf[pos], "Accept-Language: zh-CN,zh;q=0.9\r\n");pos += sprintf(&buf[pos], "Cookie: language=zh\r\n");pos += sprintf(&buf[pos], "\r\n");printf("%s\r\n", buf);int len = send(socket_fd, buf, strlen(buf), 0);printf("发送长度是%d", len);}/**********************************************************************
int prase_response(char * response_buf )
**********************************************************************/int prase_response(char * response_buf, httpauth_t *auth)
{char * begin = NULL, *end = NULL;if (strstr(response_buf, "401") != NULL){begin = strstr(response_buf, "\"");end = strstr(begin + 1, "\"");memcpy(auth->qop, begin + 1, end - begin - 1);auth->qop[end - begin - 1] = 0;begin = strstr(end + 1, "\"");end = strstr(begin + 1, "\"");memcpy(auth->realm, begin + 1, end - begin - 1);auth->realm[end - begin - 1] = 0;begin = strstr(end + 1, "\"");end = strstr(begin + 1, "\"");memcpy(auth->nonce, begin + 1, end - begin - 1);memcpy(auth->cnonce, auth->nonce, 16);}else if (strstr(response_buf, "200") != NULL)printf("the servers return 200 ok\r\n");return 0;}

程序源码百分之九十来自这里 github :https://github.com/kyhkl/hivisoion_projcet.git

通过isapi协议抓拍图片相关推荐

  1. Qt音视频开发31-Onvif抓拍图片

    一.前言 抓拍是个很重要的功能,比如在报警视频联动中需要一张实时的图片,很多SDK不提供抓拍功能,而通过预览抓图,得到的图片已不具有实时性,那如何得到实时的图片呢?现在的IPC基本上都支持ONVIF协 ...

  2. Win10系统C++调用OpenCV实现网络摄像头录像和抓拍图片

    1 前言 前边文章介绍了在WIN10系统上,分别用C++和Python调用OpenCV接口,播放本地和网络摄像头视频.本篇我们来看一下,用C++如何调用OpenCV接口,打开网络摄像头的视频,对其进行 ...

  3. 海康摄像头的ISAPI协议

    海康威视是一家领先的视频监控设备制造商,其摄像头产品可以通过 ISAPI(Intelligent Security Application Programming Interface)协议进行控制和管 ...

  4. python版海康摄像头抓拍图片

    python版海康摄像头抓拍图片 最近尝试使用海康摄像头做项目,里面有个图片抓拍的环节,我参考了网上的资料用OpenCV实现的,具体代码如下: #!/usr/bin/env python # # 这个 ...

  5. 如何修改相机码流参数和抓拍图片大小?

    Q:如何修改相机码流参数和抓拍图片大小? A:进入[配置]>[图像配置]>[编码]中,可以对相机的编码相关选项进行配置. 图像采集制式指相机采集图像的制式,默认情况下不需要修改. 主码流部 ...

  6. 移远EC20 Opencpu方案调试记录 - 摄像头ffmpeg抓拍图片 ftp上传服务器 源码(郑州新正圆)

    最近调试ec20  opencpu方案, 摄像头品牌:雄迈 功能要求:摄像头抓拍图片后通过ftp上传到阿里云服务器 图1.运行效果 具体程序实现源码 图2.源码1 图3.源码2 图4.源码3 图5.j ...

  7. java实现调用本地摄像头并实现抓拍图片功能

    上一篇讲了调用本地摄像头的方法,这一篇在上一篇的基础上再实现抓拍图片并保存至本地! OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);//0 ...

  8. 图片服务器是用什么协议,CCO协议是什么意思?CCO协议的图片能商用吗?

    你现在一般是在哪里找配图?百度?互联网?还是从别人的文章里面直接复制粘贴用?是不是用完之后心里发慌,害怕侵权?毕竟现在很多图片上面都标示着版权还有水印. 那怎么才能找到不会侵权的图片呢?首先我们需要找 ...

  9. java中抓拍图像_JavaCV调用摄像头并抓拍图片保存到本地

    添加依赖 org.bytedeco javacv-platform 1.4.1 org.bytedeco.javacpp-presets opencv-platform 3.4.1-1.4.1 jun ...

  10. C++中的Socket编程使用协议发送图片

    使用: (1)首先运行服务端,待服务端运行起来: (2)最后运行客户端,输入要传输文件到哪个目标机器的IP地址: (3)输入传输文件的路径及文件(完成的路径),其中包含文件的类型,也就是后缀需要包含( ...

最新文章

  1. SpringBoot高级篇MongoDB之修改基本使用姿势
  2. Linux-Ubuntu中使用apt进行软件的安装与卸载
  3. Linux服务-DHCP服务部署
  4. Chapter 5 Blood Type——24
  5. MySql的Delete、Truncate、Drop分析
  6. 第三节 整型和浮点型
  7. Python--day21--包
  8. boost context上下文切换
  9. java低层源码_Java线程池及其底层源码实现分析
  10. 图像通道变换python-opencv
  11. Android音视频开发(一)音视频基础知识
  12. 推荐两个高仿抖音 App 项目
  13. win2008虚拟化服务器配置,玩转Windows Server 2008自带的虚拟化功能
  14. 用户密码MD5和SHA加密
  15. 魔兽争霸3技术分析资源汇总
  16. c++ primer kindle_kindle全系列使用墨水屏版微信读书解决方法,你的无限卡有用了...
  17. 软件供应链安全——组件漏洞的治理
  18. 笔试强训48天——day29
  19. 【2019-游记】中山纪念中学暑期游Day5
  20. linux(07)之内核系统调用

热门文章

  1. 程序设计基础知识点整理,超全!!!
  2. 为什么要选择crm私有化布署?
  3. codesys 实现冒泡排序
  4. 分枝定界法,例题梳理
  5. 组态王bitset用法_组态王使用问题解答
  6. python 实现一个属于自己的语音播报器
  7. 【程序】STM32F407VE单片机驱动两片TJA1050 CAN收发器并进行双CAN通信
  8. pacpng文件格式说明
  9. 联创机房管理系统服务器密码,高校机房管理系统解决方案.doc
  10. 服务器上文件拒绝访问,云服务器文件访问被拒绝访问