前言
寫系列文章的時候[前言]部分變得無言了,可能來得順利了點吧: ) 本章中提供的封裝均是我用笨辦法從<<hikvision 闆卡網絡開發包程式設計手冊v4.7>>和<<ds-4000hc、hcs、hc+、hf、hs、md卡的windows程式設計指南v4.3>>中拷貝出來并參照vc++代碼進行整理的,主要是針對hikserver.dll和ds40xxsdk.dll的調用封裝。
注意
本系列文章限于學習交流,注重過程,由于涉及公司,是以不提供源代碼下載下傳,非常抱歉!!但是請大家放心,核心、實作以及其他能夠貼出來的代碼我都會貼出來,并且争取盡所能的回答留言裡的每一個問題,感謝大家關注,歡迎交流 :)
系列
正文
1. hikserver.dll
using system;
using system.collections.generic;
using system.text;
using system.runtime.interopservices;
namespace hikserver
{
public struct pserver_videoinfo
{
/// <summary>
/// 序列号
/// byte m_datatype[64];
/// </summary>
[marshalas(unmanagedtype.byvalarray, sizeconst = 64)]
public byte[] m_datatype;
/// 系統的通道個數
/// byte m_channum;
public byte m_channum;
/// 逾時等待時間,1-300機關:分鐘
/// dword m_waittime;
public int m_waittime;
/// 目前沒有使用
/// dword m_bufnum;
public ulong m_bufnum;
}
//[structlayout(layoutkind.sequential)]
//public struct pserver_videoinfo
//{
// public intptr m_datatype; //序列号
// public byte m_channum;//系統的通道個數
// public int m_waittime;//逾時等待時間,1-300機關:分鐘
// public int m_bufnum;//目前沒有使用
//}
/// <summary>
/// 通道資料類型
/// </summary>
public enum channeldatatype
normal = 50,
dialing,
smallpic
/// vc++demo:委托内調用setibpmode(channelhandle[port],211,2,2,framerat);
/// <param name="port"></param>
/// <param name="framerat"></param>
public delegate void setibp(int port, int framerat);
/// vc++demo:委托内調用captureiframe(channelhandle[port]);
public delegate void makeiframe(int port);
/// vc++demo:委托内調用startvideocapture(channelhandle[port]);
/// <param name="nchannel"></param>
public delegate void startcap(int nchannel);
/// vc++demo:委托内調用stopvideocapture(channelhandle[port]);
public delegate void stopcap(int nchannel);
/// 驗證使用者名密碼
/// <param name="username"></param>
/// <param name="namelen"></param>
/// <param name="password"></param>
/// <param name="passlen"></param>
/// <returns></returns>
[unmanagedfunctionpointer(callingconvention.stdcall)]
public delegate int checkpassword(string username, ushort namelen, string password, ushort passlen);
/// 驗證ip
/// vc++demo:return 0;
/// <param name="nip"></param>
public delegate int checkip(int nchannel, string nip);
public static class hikserver
public static readonly uint wm_user = 0x0400;
/// 啟動服務端
/// 傳回true表示成功,傳回false表示失敗
/// <code>
/// bool __stdcall mp4_serverstart(pserver_videoinfo videoinfo);
/// </code>
/// <param name="videoinfo"></param>
/// <returns></returns>
[dllimport("hikserver.dll")]
public static extern int mp4_serverstart(ref pserver_videoinfo videoinfo);
/// 停止服務端
/// bool __stdcall mp4_serverstop();
public static extern bool mp4_serverstop();
/// 擷取伺服器狀态
/// 傳回true表示伺服器已經啟動,傳回false表示伺服器沒有啟動
/// bool __stdcall mp4_servergetstate(word * clientnum);
/// typedef unsigned short word;
/// <param name="clientnum">表示目前與伺服器相連的用戶端資料</param>
public static extern bool mp4_servergetstate(out ushort clientnum);
/// 給用戶端發送指令碼
/// 和函數mp4_serverstringtoclient不同,它給正連接配接在該通道上的所有用戶端發送指令碼。
/// 傳回true表示成功,傳回false表示失敗
/// bool __stdcall mp4_servercommandtoclient(char ccommand,char nchannel);
/// <param name="ccommand">指令碼</param>
/// <param name="nchannel">通道号</param>
public static extern void mp4_servercommandtoclient(int ccommand, int nchannel);
/// 設定接收指令碼的相關參數
/// void __stdcall mp4_serversetmessage(uint nmessage,hwnd hwnd);
/// <param name="nmessage">對應接收程式的消息</param>
/// <param name="hwnd">應用程式視窗句柄</param>
public static extern void mp4_serversetmessage(uint nmessage, intptr hwnd);
/// 設定是否進行ip驗證。
/// 如果進行ip驗證,調用該函數,那麼每次用戶端連接配接的時候,會調用checkip。
/// 如果不進行ip驗證,不需要調用該函數。
/// 如果調用了mp4_servercheckip之後,又想取消ip驗證,隻需要調用mp4_servercheckip(null)。
/// void __stdcall mp4_servercheckip(int(callback *checkip)(dword nchannel,char* nip));
/// checkip函數說明:nchannel表示通道号,nip表示用戶端的ip位址。傳回0表示驗證通過,傳回-1
/// 表示驗證沒有通過。
public static extern void mp4_servercheckip(checkip cip);
/// 設定是否進行使用者身份驗證。
/// 使用同mp4_servercheckip。
/// 目前namelen和password兩個值無效,都是50,并不表示使用者名和密碼的實際長度。使用者名和密碼必須小于50個位元組。
/// 說明:
/// 1>因為開發包對使用者名和密碼不做任何處理,隻是簡單地分别發送50位元組的資料到服務端,是以在驗證
/// 的實作過程中,使用者可以通過設定标志位的方法來确定使用者名和密碼的實際長度。
/// 2>也可以同時進行ip驗證和使用者身份驗證。在開發包中先進行使用者身份驗證,再進行ip驗證。
/// 7. void __stdcall mp4_servercheckpassword(int(callback *checkpassword)(char *username,word namelen,char *password,word passlen));
/// checkpassword函數說明:username表示使用者名,namelen表示使用者名字元串長度,password表示密碼,passlen表示密碼字元串長度。
/// <param name="nmessage"></param>
/// <param name="hwnd"></param>
public static extern void mp4_servercheckpassword(checkpassword cp);
/// 往發送緩存寫資料。
/// 網絡開發包通過這個接口獲得闆卡的資料。
/// 現在開發包内部不會直接調用startvideocapture和stopvideocapture函數,而是通過startcap和stopcap
/// 來啟動和停止捕獲資料。如果使用者調用stopvideocapture或者停止調用mp4_serverwritedata都會使客戶
/// 端無法收到資料。
/// 8. void __stdcall mp4_serverwritedata(dword nchannel,uchar *ppacketbuffer, dword npacketsize, int frametype, int breakable);
/// typedef unsigned long dword;
/// typedef unsigned char uchar;
/// <param name="nchannel">通道号。</param>
/// <param name="ppacketbuffer">緩沖區指針。</param>
/// <param name="npacketsize">緩沖區長度。 </param>
/// <param name="frametype">幀類型。</param>
/// <param name="breakable">readstreamdata的傳回值</param>
public static extern void mp4_serverwritedata(ulong nchannel, string ppacketbuffer, ulong npacketsize, int frametype, int breakable);
/// 設定啟動捕獲的回調。
/// 9. void __stdcall mp4_serversetstart(void(callback *startcap)(int nchannel));
/// startcap函數說明:使用者實作這個函數,隻需要調用startvideocapture。
/// nchannel表示通道号。
/// <param name="sc"></param>
public static extern void mp4_serversetstart(startcap sc);
/// 設定停止捕獲的回調。
/// 10. void __stdcall mp4_serversetstop(void(callback *stopcap)(int nchannel));
/// stopcap函數說明:使用者實作這個函數,隻需要調用stopvideocapture。
public static extern void mp4_serversetstop(stopcap sc);
/// 讀取用戶端消息。
/// 讀取用戶端mp4_clientcommandtoserver函數發送過來的消息(不超過900位元組),消息的内容和長度由使用者自己定義。
/// 11. void __stdcall mp4_serverreadlastmessage(char *m_sip,char *m_scommand,word *m_wlen);
/// <param name="m_sip">消息來自哪個ip位址</param>
/// <param name="m_scommand">消息緩沖區指針。</param>
/// <param name="m_wlen">消息實際長度。 </param>
public static extern void mp4_serverreadlastmessage(stringbuilder m_sip, stringbuilder m_scommand, out ushort m_wlen);
/// 給用戶端發送消息字元串。
/// 12. bool __stdcall mp4_serverstringtoclient(lpctstr m_laddrip,char *m_scommand, word m_wlen);
/// typedef lpcstr lpctstr;
/// typedef const char *lpcstr
/// <param name="m_laddrip">用戶端ip位址。</param>
/// <param name="m_wlen">消息實際長度。</param>
/// <returns>傳回true表示成功,傳回false表示失敗</returns>
public static extern bool mp4_serverstringtoclient(string m_laddrip, string m_scommand, ushort m_wlen);
/// 對nchannel通道的網絡連接配接進行複位。
/// 如果需要單獨終止該通道目前的用戶端連接配接,或者該通道目前的網絡狀态處于異常狀況,都可以調用該函
/// 數。該函數對任何闆卡sdk對應操作都不會有任何影響。
/// 13. void __stdcall mp4_serverresetchannel(dword nchannel);
public static extern void mp4_serverresetchannel(ulong nchannel);
/// 設定服務端的網絡端口号和用戶端的網絡端口号。
/// 服務端使用端口如下(假設dserverport=5050):
/// tcp隻需要占用5050。
/// udp和多點傳播需要占用5050、5060----(5060+2*通道個數)。
///
/// 用戶端使用端口如下(假設dclientport =6050):
/// tcp和多點傳播隻需要占用6057。
/// udp需要占用6057、6060----(6060+2*視窗個數)。
/// 14. bool __stdcall mp4_serversetnetport(word dserverport,word dclientport);
/// <param name="dserverport">服務端的起始網絡端口号。必須和函數mp4_clientsetnetport的dserverport參數相同。</param>
/// <param name="dclientport">用戶端的網絡端口号。必須和函數mp4_clientsetnetport的dclientport參數相同。</param>
/// <returns>傳回true表示成功,傳回false表示失敗。</returns>
public static extern int mp4_serversetnetport(ushort dserverport, ushort dclientport);
/// 設定多點傳播的ttl參數。
/// 注意: 如果您不調用函數mp4_serversetttl,預設ttl值是32。
/// mp4_serversetttl設定的值在mp4_serverstop之後會失效,恢複成預設的32,是以您如果需要指定ttl
/// 大小,每次在mp4_serverstart之前都需要調用mp4_serversetttl。
/// 15. bool __stdcall mp4_serversetttl(unsigned char cttlval);
/// <param name="cttlval">ttl值。1-255。</param>
public static extern int mp4_serversetttl(byte cttlval);
/// 設定發送緩沖區大小。
/// 注意: 如果您不調用函數mp4_serversetbufnum,預設緩沖區是30。
/// mp4_serversetbufnum設定的值在mp4_serverstop之後會失效,恢複成預設的30,是以您如果需要指定
/// 緩沖區大小,每次在mp4_serverstart之前都需要調用mp4_serversetbufnum。
/// 16. bool __stdcall mp4_serversetbufnum(dword nchannel,word dbufnum);
/// <param name="dbufnum">緩沖區大小。機關是8k,如果dbufnum=10,那麼緩沖區大小為80k,建議設定成30。範圍:10-100。</param>
public static extern int mp4_serversetbufnum(ushort nchannel, ushort dbufnum);
/// 設定自動調節幀率的回調函數,隻在電話線連接配接中使用。
/// 在回調函數setibp中隻調用setibpmode函數
/// 17. void __stdcall mp4_serversetibpmode(void(callback *setibp)(int nchannel,int framerat));
/// <param name="setibp"></param>
public static extern void mp4_serversetibpmode(setibp setibp);
/// 設定連接配接用戶端的等待時間和嘗試次數。
/// 說明:當服務端給用戶端發送消息的時候,需要等待用戶端應答,以保證用戶端收到消息,如果失敗,還
/// 可以繼續嘗試dtrynum-1次發送。
/// 注意:
/// 1>如果這兩個參數設得太小,當網絡繁忙或用戶端繁忙的時候,可能會導緻發送消息失敗;如果這兩個參
/// 數設得太大,當試圖連接配接的用戶端不存在(ip位址錯誤、或者關機、或者沒有啟動用戶端軟體),消息發送
/// 函數會等待很久才傳回。
/// 2>這兩個參數設定之後一直有效,直到下次調用該函數修改。
/// 18. bool __stdcall mp4_serversetwait(dword deachwaittime,dword dtrynum);
/// <param name="deachwaittime">等待時間。機關是毫秒,範圍300-10000。如果不調用這個函數,預設是2000。</param>
/// <param name="dtrynum">嘗試次數。範圍1-50。如果不調用這個函數,預設是2次。</param>
public static extern bool mp4_serversetwait(ulong deachwaittime, ulong dtrynum);
/// 給連接配接在指定通道上的所有用戶端發送消息字元串。
/// 19. bool __stdcall mp4_serverstringtoclient_other (char nchannel,char *m_scommand, word m_wlen);
/// <returns>傳回true表示成功,傳回false表示失敗。 </returns>
public static extern bool mp4_serverstringtoclient_other(int nchannel, string m_scommand, ushort m_wlen);
/// 動态切換通道資料類型。
/// 注意:調用mp4_serverchangechantype之前必須調用stopvideocapture。(詳見demo)
/// 20. bool __stdcall mp4_serverchangechantype(char nchannel,char ctype);
/// <param name="nchannel">通道号。 </param>
/// <param name="ctype">通道資料類型,是否支援電話線連接配接(normal或者dialing)</param>
public static extern bool mp4_serverchangechantype(char nchannel, char ctype);
/// 設定回調,重新生成一個i幀。
/// 21. void __stdcall mp4_serversetcapiframe(void(callback *makeiframe) (int port));
/// <param name="mf"></param>
public static extern void mp4_serversetcapiframe(makeiframe mf);
/// 擷取版本号。
/// 22. dword __stdcall mp4_servergetsdkversion();
public static extern ulong mp4_servergetsdkversion();
/// 設定每個通道的多點傳播組位址和網絡端口号。
/// 說明:
/// 1>目前的多點傳播組采用了兩種方式:一是開發包内部配置設定,使用者不需要考慮多點傳播組參數細節,預設采用這種
/// 方式;另一種是調用mp4_servercastgroup設定多點傳播組參數。
/// 2>使用者可以通過mp4_servercastgroup修改參數bset,在兩種方式之間做切換。
/// 每個多點傳播組會占用wport開始的4個端口。
/// 23. bool __stdcall mp4_servercastgroup(bool bset,dword dchannel, char *sip, word wport);
/// <param name="bset">是否使用自定義的多點傳播組位址和網絡端口号。true表示使用,false表示仍然沿用開發包内部自動配置設定的多點傳播位址和網絡端口号。 </param>
/// <param name="dchannel">通道号。每個通道号對應的多點傳播組位址和網絡端口号都是單獨設定的。</param>
/// <param name="sip">多點傳播組位址。</param>
/// <param name="wport">多點傳播組網絡端口号</param>
public static extern bool mp4_servercastgroup(bool bset, ulong dchannel, string sip, ushort wport);
/// 設定每個通道的最大使用者數量。
/// 24. bool __stdcall mp4_servermaxuser(dword dwchannel,int nmaxnum)
/// <param name="dwchannel">通道号。</param>
/// <param name="nmaxnum">使用者數量。</param>
public static extern int mp4_servermaxuser(uint dwchannel, int nmaxnum);
/// 往發送緩存寫資料。網絡開發包通過這個接口獲得闆卡的資料。
/// 現在開發包内部不會直接調用startvideocapture和stopvideocapture函數,而是通過startcap
/// 和stopcap來啟動和停止捕獲資料。如果使用者調用stopvideocapture或者停止調用mp4_serverwritedataex
/// 都會使用戶端無法收到資料。原來的mp4_serverwritedata内部調用mp4_serverwritedataex完成相關功能。
/// 25. void __stdcall mp4_serverwritedataex(dword nport,uchar *ppacketbuffer,dword npacketsize,int frametype,int breakable,int nimgformat)
/// <param name="nport">通道号。</param>
/// <param name="npacketsize">緩沖區長度。</param>
/// <param name="nimgformat">
/// 圖像格式。nimgformat 為0 時表示發送主通道的音視訊資料
/// nimgformat 為1 時表示發送子通道的音視訊資料。
/// </param>
//public unsafe static extern void mp4_serverwritedataex(uint nport, void* ppacketbuffer, uint npacketsize, int frametype, int breakable, int nimgformat);
public static extern void mp4_serverwritedataex(int nport, intptr ppacketbuffer, int npacketsize, int frametype, int breakable, int nimgformat);
//public static extern void mp4_serverwritedataex(uint nport, byte[] ppacketbuffer, uint npacketsize, int frametype, int breakable, int nimgformat);
}
修改記錄
1. 2009-8-19,修改了mp4_serverreadlastmessage,非常感謝 阿斯頓啊 的貢獻!
修正前:public static extern void mp4_serverreadlastmessage(string m_sip, string m_scommand, out ushort m_wlen);
修正後:public static extern void mp4_serverreadlastmessage(stringbuilder m_sip, stringbuilder m_scommand, out ushort m_wlen);
結束
在後續的文章中本文中api仍然可能會變動,畢竟我們用的隻是其中的一部分,我會随時更新,感謝繼續關注。本來是作為一篇文章釋出的,發現代碼過長,插入都費老半天,所有拆開成上下了!!
轉載:http://www.cnblogs.com/over140/archive/2009/03/10/1407504.html