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. Java 连接各种数据库
  2. Oracle入门(十四.10)之显式游标简介
  3. LeetCode 1161. 最大层内元素和(层序遍历)
  4. 每卖出一部新款iPhone SE,苹果就要赚1500元?
  5. POJ 2912 Rochambeau(难,好题,枚举+带权并查集)
  6. 阿里云磐久服务器M系列研发之路
  7. 蓝绿色——三色配色篇
  8. 图文详解 | 万用表的使用与口诀!十足干货,不要错过!
  9. org.eclipse.core.runtime.CoreException: Plug-in org.eclipse.jdt.ui was unable to load class org.ecli
  10. 网络安全形势严峻:国内黑灰产业产值达千亿
  11. Pitest内存泄露分析 (工具使用IDEA、Jprofiler)
  12. JS+CSS竖向折叠滑动菜单代码
  13. 思考互联网发展三阶段
  14. 在router中使用pinia报错解决
  15. 哈工大计算机网络week4学习总结
  16. 用例建模-绘制用例图
  17. mysql积累--索引
  18. 如何查看服务器内存信息,如何查看服务器内存信息
  19. 微信小程序iOS使用input输入时placeholder及输入内容消失或隐藏
  20. C语言见缝插针游戏,见缝插针玩游戏

热门文章

  1. 房产中介管理系统网站完整源码
  2. 云打印SDK来袭,支持飞鹅云,芯烨云,易联云,优声云等云打印机
  3. Cisco Packet Tracer 实验教程
  4. 拼音表大全图_【居家乐学】让拼音活起来
  5. 网络协议之NAT穿透原理
  6. thinksnsv4.6运行php,开源微博系统(ThinkSNS) v4.6.1
  7. iOS 在线下载字体
  8. 安装Ubuntu详细教程
  9. win系统下非系统盘msdia.dll文件怎么处理
  10. 插值法(三次样条插值)