c# DllImport 错误处理的不足及解决办法

一般而言DllImport 是十分方便的,但是当出现错误时,他给出的错误也十分模糊,同时是不全面的。


比如,之前就遇到一个第三方dll, DllImport 死活说找不到这个dll.


但是我很确定错在这个dll,而且路径也对。


没办法,只能做个vc调用尝试,然后vc调用得到了这个消息:

这才发现,原来找不到的其实不是第三方dll,而是这个第三方另外调用的dll,但是c#完全不能得到这个消息。

无奈之下,为了以后方便,只能自己做了个测试函数,来测试装载第三方dll:


  public static class DllTest
    {
        public static bool TestDll(string strDllPath)
        {
            try
            {
                var test = NativeMethods.LoadLibrary(strDllPath);
                MessageBox.Show(test.ToInt32().ToString());
                return true;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
                return false;
            }
        }
    }


你可以在DllImport之前先调用这个函数做一下测试!

如果返回非0就代表正常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【面试题库网整理 .net 面试题(附答案)(四)】 7. 某一密码仅使用K、L、M、N、O共5个字母,密码中的单词从左向右排列,密码单词必须遵循如下规则: (1) 密码单词的最小长度是两个字母,可以相同,也可以不同 (2) K不可能是单词的第一个字母 (3) 如果L出现,则出现次数不止一次 (4) M不能使最后一个也不能是倒数第二个字母 (5) K出现,则N就一定出现 (6) O如果是最后一个字母,则L一定出现 问题一:下列哪一个字母可以放在LO中的O后面,形成一个3个字母的密码单词? A) K B)L C) M D) N 答案:B 问题二:如果能得到的字母是K、L、M,那么能够形成的两个字母长的密码单词的总数是多少? A)1个 B)3个 C)6个 D)9个 答案:A 问题三:下列哪一个是单词密码? A) KLLN B) LOML C) MLLO D)NMKO 答案:C 8. 62-63=1 等式不成立,请移动一个数字(不可以移动减号和等于号),使得等式成立,如何移动? 答案:62移动成2的6次方 new有几种用法 第一种:new Class(); 第二种:覆盖方法 public new XXXX(){} 第三种:new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。 2.如何把一个array复制到arrayList里 foreach( object o in array )arrayList.Add(o); 3.datagrid.datasouse可以连接什么数据源 [dataset,datatable,dataview] dataset,datatable,dataview , IList 4.概述反射和序列化 反射:程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性 序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。 5.概述o/r mapping 的原理 利用反射,配置 将类于数据库表映射 7.用sealed修饰的类有什么特点 sealed 修饰符用于防止从所修饰的类派生出其它类。如果一个密封类被指定为其它类的基类,则会发生编译时错误。 密封类不能同时为抽象类。 sealed 修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。具体说来,由于密封类永远不会有任何派生类,所以对密封类的实例的虚拟函数成员的调用可以转换为非虚拟调用来处理。 11.详述.NET里class和struct的异同! class:放在 ? struct放在? struct值传递 类与结构有很多相似之处:结构可以实现接口,并且可以具有与类相同的成员类型。然而,结构在几个重要方面不同于类:结构为值类型而不是引用类型,并且结构不支持继承。结构的值存储在“在堆栈上”或“内联”。细心的程序员有时可以通过聪明地使用结构来增强性能。 12.概述.NET里对 remoting 和 webservice 两项技术的理解和实际中的应用。 远程逻辑调用,remoing接口只能用在.net中 13.什么是code-behind技术 aspx and cs 14.概述三层结构体系 web/business/dataaccess 15.asp.net如何实现MVC模式,举例说明! web/business/dataaccess 2.什么是ASP.net中的用户控件 答:用户控件就是.ascx扩展名的东西喽,可以拖到不同的页面中调用,以节省代码.比如登陆可能在多个页面上有,就可以做成用户控件,但是有一个问题就是用户控件拖到不同级别的目录下后里面的图片等的相对路径会变得不准确,需要自已写方法调整. 3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释? 答:装箱就是把值类型转成引用类型,从MS IL角度看好像是boxing,没记错的话是把值从堆栈转到堆中.拆箱相反,重载就是指一个方法名同,参数个数不同,返回值可以相同的方法.CLR是通用语言运行时,其它的不清楚. 4.列举一下你所了解的XML技术及其应用 答:XML可是好东西,保存配置,站与站之间的交流,WEB SERVICE都要用它. 5.值类型和引用类型的区别?写出C#的样例代码。 答:结构是值类型,类是引用类型,所以传结构就是值类型的应用啦,传对象或类就是引用类型的,这个不用多写了吧. 6.ADO.net中常用的对象有哪些?分别描述一下。 答:connection command sqladapter dataset datatable dataview等等.写不完了. 7.如何理解委托? 答:据说相当于函数指针,定义了委托就可以在不调用方法名称的情况下调用那个方法. msdn2005中是这样解释的: 委托具有以下特点: 委托类似于 C++ 函数指针,但它是类型安全的。 委托允许将方法作为参数进行传递。 委托可用于定义回调方法。 委托可以链接在一起;例如,可以对一个事件调用多个方法方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。 C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。 【面试题库网整理 .net 面试题(附答案)(三)】 22.您要创建一个显示公司员工列表的应用程序。您使用一个DataGrid控件显示员工的列表。您打算修改这个控件以便在这个Grid的Footer显示员工合计数。请问您应该怎么做?( C? ) A.重写OnPreRender事件,当Grid的Footer行被创建时显示合计数。 B.重写OnItemCreated事件,当Grid的Footer行被创建时显示合计数。 C.重写OnItemDataBound事件,当Grid的Footer行被创建时显示合计数。 D. 重写OnLayout事件,当Grid的Footer行被创建时显示合计数。 23.您要创建ASP.NET应用程序用于运行AllWin公司内部的Web站点,这个应用程序包含了50个页面。您想要配置这个应用程序以便当发生一个HTTP代码错误时它可以显示一个自定义的错误页面给用户。您想要花最小的代价完成这些目标,您应该怎么做?(多选)( CD )   A.在这个应用程序的Global.asax文件中创建一个Application_Error过程去处理ASP.NET代码错误。   B.在这个应用程序的Web.config文件中创建一个applicationError节去处理ASP.NET代码错误。   C.在这个应用程序的Global.asax文件中创建一个CustomErrors事件去处理HTTP错误。   D.在这个应用程序的Web.config文件中创建一个CustomErrors节去处理HTTP错误。   E.在这个应用程序的每一页中添加一个Page指示符去处理ASP.NET 代码错误。   F. 在这个应用程序的每一页中添加一个Page指示符去处理ASP.NET HTTP错误。 24.您的公司有一个DB Server,名为AllWin,其上装了MS SQLSERVER 2000。现在需要您写一个数据库连接字符串,用以连接AllWin上SQL SERVER中的一个名为PubBase实例的Test库。请问,应该选择下面哪一个字符串?( B )   A. “Server=AllWin;Data Source=PubBase;Initial Catalog=Test;Integrated Security=SSPI”   B. “Server= AllWin;Data Source=PubBase;Database=Test;Integrated Security= SSPI”   C. “Data Source= AllWin \PubBase;Initial Category=PubBase;Integrated Security= SSPI”   D. “Data Source= AllWin \ PubBase;Database=Test;Integrated Security= SSPI” 25.您为AllWin公司创建了一个ASP.NET应用程序。这个应用程序调用一个 Xml Web Service。这个 Xml Web Service 将返回一个包含了公司雇员列表的DataSet对象。请问您该如何在这个程序中使用这个 Xml Web Service?( ? )   A.在“引用”对话框的.Net标签中选择 System.Web.Services.dll。   B.在“Web引用”对话框中输入这个 XML Web service 的地址。   C.在您的 Global.asax.cs 中添加一条 using 语句并指定这个 XML Web service 的地址。   D.在您的 Global.asax.cs 中写一个事件处理器导入这个 Xml Web Service 相应的 .wsdl 和 .disco 文件。 26.您要创建一个ASP.NET应用程序在DataGrid控件中显示一个经过排序的列表。产品数据被存放于一个名为PubBase的Microsoft SQL Server 数据库。每个产品的主键是ProductID,Numeric型并且每个产品有一个字母描述字段,名为ProductName。您使用一个SqlDataAdapter对象和一个SqlCommand对象通过调用一个存储过程从数据库中获取产品数据。您将SqlCommand对象的CommandType属性设置为CommandType.StoredProcedure,并将它的CommandText属性设置为procProductList。您成功的获取了一个DataTable对象,其中是已经按ProductID降序排列的产品列表。您打算显示以相反的字母顺序排列的ProductName,请问该怎么做? ( B )   A. 将SqlCommand对象的CommandType属性修改为CommandType.Text,将CommandText属性修改为”SELECT * FROM procProductList ORDER BY ProductName DESC”。然后将这个DataTable对象绑定到DataGrid控件。   B. 创建一个基于这个DataTable对象的新的DataView并将这个DataView的Sort属性设置为“ProductName DESC”。然后将这个DataView对象绑定到DataGrid控件。   C. 将DataGrid控件的AllowSorting属性设置为True,并将DataGridColumn的SortExpression属性设置为 “ProductName DESC”.以显示ProductName。然后将这个DataTable对象绑定到DataGrid控件。   D. 将DataTable对象的DisplayExpression属性设置为 “ORDER BY ProductName DESC”.。然后将这个DataTable对象绑定到DataGrid控件。 76.C#代码实现,确保windows程序只有一个实例(instance) ///<summary> ///应用程序的主入口点。 ///</summary> [STAThread] staticvoid Main() { //防止程序多次运行 if(!OneInstance.IsFirst("GetPayInfo")) { MessageBox.Show ("警告:程序正在运行中! 请不要重复打开程序!可在右下角系统栏找到!","程序错误提示:",MessageBoxButtons.OK,MessageBoxIcon.Stop); return; } Application.Run(new Form1()); } // ******************* 防止程序多次执行 ************************** publicabstractclass OneInstance { ///<summary> ///判断程序是否正在运行 ///</summary> ///<param name="appId">程序名称</param> ///<returns>如果程序是第一次运行返回True,否则返回False</returns> publicstaticbool IsFirst(string appId) { bool ret=false; if(OpenMutex(0x1F0001,0,appId)==IntPtr.Zero) { CreateMutex(IntPtr.Zero,0,appId); ret=true; } return ret; } [DllImport("Kernel32.dll",CharSet=CharSet.Auto)] privatestaticextern IntPtr OpenMutex( uint dwDesiredAccess, // access int bInheritHandle, // inheritance option string lpName // object name ); [DllImport("Kernel32.dll",CharSet=CharSet.Auto)] privatestaticextern IntPtr CreateMutex( IntPtr lpMutexAttributes, // SD int bInitialOwner, // initial owner string lpName // object name ); } 【面试题库网整理 .net 面试题(附答案)(二)】 8.以下代码段中能否编译通过?请给出理由。 try { } catch(FileNotFoundException e1) { } catch(Exception e2) { } catch(IOException e3) { } catch { } 9.对于一个实现了IDisposable接口的类,以下哪些项可以执行与释放或重置非托管资源相关的应用程序定义的任务?(多选) ( ABC ) A.Close B.DisposeC.Finalize D.using E.Quit 10.Net依赖以下哪项技术实现跨语言互用性?( C ) A.CLR B.CTS C.CLS D.CTT 11.请问: String类与StringBuilder类有什么区别?为什么在.Net类库中要同时存在这2个类?(简答) 如果要操作一个不断增长的字符串,尽量不用String类,改用StringBuilder类。两个类的工作原理不同:String类是一种传统的修改字符串的方式,它确实可以完成把一个字符串添加到另一个字符串上的工作没错,但是在.NET框架下,这个操作实在是划不来。因为系统先是把两个字符串写入内存,接着删除原来的String对象,然后创建一个String对象,并读取内存中的数据赋给该对象。这一来二去的,耗了不少时间。而使用System.Text命名空间下面的StringBuilder类就不是这样了,它提供的Append方法,能够在已有对象的原地进行字符串的修改,简单而且直接。当然,一般情况下觉察不到这二者效率的差异,但如果你要对某个字符串进行大量的添加操作,那么StringBuilder类所耗费的时间和String类简直不是一个数量级的。 12.以下哪个类是int的基类?( ) A.Int32 B.Object C.ValueType D.Int16 二、C# 部分* 13.以下哪些可以作为接口成员? (多选) ( ABDE ) A.方法B.属性C.字段D.事件E.索引器 F.构造函数G.析构函数 14.以下关于ref和out的描述哪些项是正确的?(多选) ( ACD ) A.使用ref参数,传递到ref参数参数必须最先初始化。 B.使用out参数,传递到out参数参数必须最先初始化。 C.使用ref参数,必须将参数作为ref参数显式传递到方法。 D.使用out参数,必须将参数作为out参数显式传递到方法。 15.“访问范围限定于此程序或那些由它所属的类派生的类型”是对以下哪个成员可访问性含义的正确描述?( B ) A.public B.protected C.internal D.protected internal 16.class Class1 { private static int count = 0; static Class1() { count++; } public Class1() { count++; } } Class1 o1 = new Class1(); Class1 o2 = new Class1(); 请问,o1.Count的值是多少?( C ) A.1 B.2 C.3 D.4 17.abstract class BaseClass { public virtual void MethodA() { } public virtual void MethodB() { } } class Class1: BaseClass { public void MethodA(string arg) { } public override void MethodB() { } } class Class2: Class1 { new public void MethodB() { } } class MainClass { public static void Main(string[] args) { Class2 o = new Class2(); Console.WriteLine(o.MethodA()); } } 请问,o.MethodA调用的是: ( A ) A.BaseClass.MethodAB.Class2.MethodA C.Class1.MethodAD.都不是 【.net 面试题系列文章一(附答案)】 1 (1)面向对象的语言具有__继承性_性、_封装性_性、_多态性 性。 (2)能用foreach遍历访问的对象需要实现 _ IEnumerable 接口或声明_ GetEnumerator 方法的类型。1.c#中的三元运算符是__?:__ 2.当整数a赋值给一个object对象时,整数a将会被__装箱___? 3.类成员有__3__种可访问形式? 4.public static const int A=1;这段代码有错误么?是什么? const成员都是static所以应该去掉static 5.float f=-123.567F; int i=(int)f; i的值现在是_-123____? 6.利用operator声明且仅声明了==,有什么错误么? 要同时修改Equale和GetHash() ? 重载了"==" 就必须重载 "!=" 7.委托声明的关键字是___ delegate ___? 8.用sealed修饰的类有什么特点?不可被继承 9.在Asp.net中所有的自定义用户控件都必须继承自_ System.Web.UI.UserControl _______? 10.在.Net中所有可序列化的类都被标记为__[serializable]___? 11.在.Net托管代码中我们不用担心内存漏洞,这是因为有了_ gC __? 12.下面的代码中有什么错误吗?_ abstract override 是不可以一起修饰______ using System; class A { public virtual void F(){ Console.WriteLine("A.F"); } } abstract class B:A { public abstract override void F(); } 13.当类T只声明了私有实例构造函数时,则在T的程序文本外部,_不可以_(可以 or 不可以)从T派生出新的类,_不可以_(可以 or 不可以)直接创建T的任何实例。 14.下面这段代码有错误么?case():不行 default; switch (i){ case(): CaseZero(); break; case 1: CaseOne(); break; case 2: dufault; CaseTwo(); break; } 15.在.Net中,类System.Web.UI.Page 可以被继承么?可以
5.36现在RTM! NEW /改进: 现在有一个内置的互动正则表达式实用!按下Ctrl + Shift + F1,或选择帮助菜单上的选项。该实用程序实现为LINQPad脚本 - 点击内置样品进行查看。 LINQPad现在包括编写交互查询一组HTML控件。不像WPF和Windows窗体控件,这些呈现在相同的输出面板的结果。要使用它们,只是实例化和甩掉他们: //所有控制住在LINQPad.Controls命名空间。 VAR = TXT新文本框()转储(); 。txt.TextInput + =(发件人,参数)=> $ “您键入{txt.Text}” 转储(); 点击这里为一个交互式的教程。 该的NuGet搜索引擎现在可以识别SemVer2抢鲜封装,并采用了新的速度更快的API。 现在,您可以参考的NuGet包,其中包括唯一的本地的DLL,如Microsoft.ChakraCore。要调用本地方法,设置查询类型为“C#程序”,并声明要调用与适当的DllImport属性前缀的方法。 LINQPad现在标识与重复扩展在Content_Types.xml属性,并自动删除重复的,这样的包装载机不会引发InvalidOperationException的NuGet包。 C#7.3现在支持。 当连接到SQL Azure的,你现在可以选择通用Active Directory身份验证,与多因素认证支持。 有在LINQPad的的Util类新方法来加载/字符串或字节数组保存到一个中央计算机存储(查询之间共享)。这些方法Util.SaveString,Util.SaveBytes,Util.LoadString和Util.LoadBytes。 LINQPad的嵌入式ILSpy现在已经更新到V4。 现在,您可以启用或在每次查询禁用编译器优化,通过启动用下面的代码查询: #LINQPad优化+ //要强制在此查询优化 #LINQPad optimize- //要强制关闭优化此查询 在SQL连接对话框,当您选择“显示在TreeView中所有数据库”选项,一个复选框,现在看来可以让你选择是否要自动填充在启动数据库列表。 (F#)使用类供应商,LINQPad现在可以正确地逃脱在自动完成列表成员名称空间。 (F#)现在有一个选项,编辑| 偏好| 高级>执行强制LINQPad始终使用其内部的F#的编译器,即使在F#已经被安装在计算机上。当F#已部分或安装不正确这可能是有用的。 当使用LPRun经由命令行来执行脚本,你现在可以明确地控制%ERRORLEVEL% - 无论是通过返回从主的整数值,或通过设置Environment.ExitCode。如前所述,如果你的脚本抛出一个异常,%ERRORLEVEL%会1。 LINQPad 5.36支持最新的实体框架核心驱动力,这与EF 2.x的所有版本进行互操作 用于.NET标准组件支持有了进一步的提高,随着.deps.json文件中列出的NuGet依赖性自动分辨率。 固定: 调试器现在可以正确步骤通过F#程序。 拆卸F#程序时,有关解决FSharp.Core.dll错误已得到修复。 通过局部变量掩盖捕获变量现在在调试本地窗口中正确显示。 当倾倒不可枚举的项目一格,可为空的bool不再导致格式错误。 当显示在自动完成列表和工具提示XML文档的摘要,标签不再理会。 造成大量的NuGet组件的编辑器性能问题已得到修复。 在证书的认证中饲料的NuGet处理的错误已经被修正了。 Util.Cache现在可以用非常大的对象可靠地使用。 对于3个显示器在Windows 10上运行时报告非常缓慢的自动完成功能的用户,这个现在应该是固定的。 此版本包含了一个解决方法.NET安全问题。
最近,正在忙基于三汇语音卡的呼叫中心的项目,真的好迷糊啊!公司在呼叫中心这方面的研发是空白,所有的资料都得从零开始收集,分析,上网查找一些前辈们的技术资料,在这里备个份,好好学习一下! --------------------------------------------------------------------------------------------------------------------- 随着语音技术的不断发展,语音卡在通信行业应用非常广泛。本节通过几个典型实例介绍语音卡程序的开发。 说明-1 实例428 语音卡电话呼叫系统 实例说明 随着科学技术的不断发展,语音卡被广泛地应用于商业软件中。本例实现了利用语音卡实现电话呼叫的功能。实例运行结果如图13.12所示。 说明-2 技术要点 本例采用东进公司开发的8路模拟语音卡,该卡采用灵活的模式化设计,可按需配置外线、内线两种模块。该语音卡可实现坐席、会议、FSK数据收发、语音合成等多种功能,并提供SDK开发工具包。 在安装完驱动程序后,相应的动态链接库(NewSig.dll和Tc08a32.dll文件)会复制到Windows的系统目录下。在语音卡的开发过程中,主要通过调用NewSig.dll和Tc08a32.dll来实现相应的功能。下面介绍这两个动态库中的主要使用函数。 (1)LoadDRV函数 该函数用于加载动态链接库。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern long LoadDRV(); 返回值:返回值为0表示成功;?1表示打开设备驱动程序错误。?2表示在读取TC08A-V.INI文件时发生错误;?3表示INI文件的设置与实际的硬件不一致时发生错误。 (2)FreeDRV函数 该函数用于关闭驱动程序。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern long EnableCard(short wusedCh, short wFileBufLen); (3)EnableCard函数 该函数用于初始化语音卡硬件,并为每个通道分配语音缓冲区。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern long EnableCard(short wusedCh, short wFileBufLen); 参数说明如下。 l wUsedCh:标识通道数量。 l WFileBufLen:标识分配的缓冲区大小。 (4)CheckValidCh函数 该函数检测在当前机器内可用的通道总数。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern short CheckValidCh(); l 返回值:通道总数量。 (5)CheckChType函数 该函数用于测试某个通道的类型。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern short CheckChType(short wChnlNo); 参数说明如下。 l wChnlNo:标识通道号。 l 返回值:为0表示内线;为1表示外线;为2表示悬空。 (6)PUSH_PLAY函数 该函数用于维持文件录放音的持续进行,需在处理函数的大循环中调用。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern void PUSH_PLAY(); (7)SetBusyPara函数 该函数用于设置要检测的挂机忙音的参数。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern void SetBusyPara(short BusyLen); 参数说明: l BusyLen:标识忙音的时间长度,单位为毫秒。 (8)RingDetect函数 该函数用于测试外线是否振铃或内线是否提机。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern bool RingDetect(short wChnlNo); 参数说明如下。
C#如何在后台捕捉按键 [此问题的推荐答案] API别忘了 using System.Runtime.InteropServices; [DllImport("user32.dll")] public static extern UInt32 RegisterHotKey(IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk); //API public Form1() { InitializeComponent(); RegisterHotKey(this.Handle, 247696411, 0, (UInt32)Keys.F10); //注册热键 } //重写消息循环 protected override void WndProc(ref Message m) { const int WM_HOTKEY = 0x0312; // m.WParam.ToInt32() 要和 注册热键时的第2个参数一样 if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == 247696411) //判断热键 { //写上你的代码 } base.WndProc(ref m); } 写上代码后 只要 在程序运行时按F10就可以触发热键更改按键可以在 注册时改 RegisterHotKey(this.Handle, 247696411, 0, (UInt32)Keys.***); http://baike.baidu.com/view/1080084.html?tp=0_10 这里有RegisterHotKey 的介绍 RegisterHotKey 函数功能:该函数定义一个系统范围的热键。 函数原型:BOOL RegisterHotKey(HWND hWnd,intid,UINT fsModifiers,UINT vk); 参数: hWnd:接收热键产生WM_HOTKEY消息的窗口句柄。若该参数NULL,传递给调用线程的WM_HOTKEY消息必须在消息循环中中进行处理。 id:定义热键的标识符。调用线程中的其他热键不能使用同样的标识符。应用功能程序必须定义一个0X0000-0xBFFF范围的值。一个共享的动态链接库(DLL)必须定义一个0xC000-0xFFFF范围的值伯GlobalAddAtom函数返回该范围)。为了避免与其他动态链接库定义的热键冲突,一个DLL必须使用GlobalAddAtom函数获得热键的标识符。 fsModifoers:定义为了产生WM_HOTKEY消息而必须与由nVirtKey参数定义的键一起按下的键。该参数可以是如下值的组合: MOD_ALT:按下的可以是任一Alt键。MOD_CONTROL:按下的可以是任一Ctrl键。 MOD_SHIFT:按下的可以是任一Shift键。 MOD_WIN:按下的可以是任一Windows按键。这些键可以用Microsoft Windows日志记录下来。 vk:定义热键的虚拟键码。 返回值:若函数调用成功,返回一个非O值。若函数调用失败,则返回值为0。若要获得更多的错误信息,可以调用GetLastError函数。 本贴来自ZDNetChina中文社区 http://bbs.zdnet.com.cn ,本贴地址:http://bbs.zdnet.com.cn/viewthread.php?tid=93775 RegisterHotKey   函数功能:该函数定义一个系统范围的热键。   函数原型:BOOL RegisterHotKey(HWND hWnd,intid,UINT fsModifiers,UINT vk);   参数:   hWnd:接收热键产生WM_HOTKEY消息的窗口句柄。若该参数NULL,传递给调用线程的WM_HOTKEY消息必须在消息循环中中进行处理。   id:定义热键的标识符。调用线程中的其他热键不能使用同样的标识符。应用功能程序必须定义一个0X0000-0xBFFF范围的值。一个共享的动态链接库(DLL)必须定义一个0xC000-0xFFFF范围的值伯GlobalAddAtom函数返回该范围)。为了避免与其他动态链接库定义的热键冲突,一个DLL必须使用GlobalAddAtom函数获得热键的标识符。   fsModifoers:定义为了产生WM_HOTKEY消息而必须与由nVirtKey参数定义的键一起按下的键。该参数可以是如下值的组合:   MOD_ALT:按下的可以是任一Alt键。MOD_CONTROL:按下的可以是任一Ctrl键。   MOD_SHIFT:按下的可以是任一Shift键。   MOD_WIN:按下的可以是任一Windows按键。这些键可以用Microsoft Windows日志记录下来。   vk:定义热键的虚拟键码。   返回值:若函数调用成功,返回一个非O值。若函数调用失败,则返回值为0。若要获得更多的错误信息,可以调用GetLastError函数。   备注:当某键被接下时,系统在所有的热键中寻找匹配者。一旦找到一个匹配的热键,系统将把WM_HOTKEY消息传递给登记了该热键的线程的消息队列。该消息被传送到队列头部,因此它将在下一轮消息循环中被移去。该函数不能将热键同其他线程创建的窗口关联起来。   若为一热键定义的击键己被其他热键所定义,则RegisterHotKey函数调用失败。   若hWnd参数标识的窗口已用与id参数定义的相同的标识符登记了一个热键,则参数fsModifiers和vk的新值将替代这些参数先前定义的值。   Windows CE:Windows CE 2.0以上版本对于参数fsModifiers支持一个附加的标志位。叫做MOD_KEYUP。   若设置MOD_KEYUP位,则当发生键被按下或被弹起的事件时,窗口将发送WM_HOTKEY消息。   RegisterHotKey可以被用来在线程之间登记热键。   速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:不支持;头文件:winuser.h;库文件:user32.lib
要改协议,,高手帮下忙。。在线等。<br>using System;<br>using System.Drawing;<br>using System.Collections;<br>using System.ComponentModel;<br>using System.Windows.Forms;<br>using System.Data;<br>using System.Messaging;<br>using System.Net.Sockets;<br>using System.Text;<br>using System.Runtime.InteropServices;<br>using System.IO;<br>using System.Threading ;<br>using System.Net;<br><br>namespace GprsServer<br>{<br> /// <summary><br> /// Form1 的摘要说明。<br> /// </summary><br> public class GprsServer : System.Windows.Forms.Form<br> {<br> /// <summary><br> /// 必需的设计器变量。<br> /// </summary><br> <br> [DllImport("User32.dll",EntryPoint="SendMessage")]<br> private static extern int <br> SendMessage(<br> int hWnd, // handle to destination window<br> int Msg, // message<br> int wParam, // first message parameter<br> string lParam // second message parameter<br> );<br> [DllImport("User32.dll",EntryPoint="FindWindow")]<br> private static extern int FindWindow(string lpClassName,string lpWindowName);<br><br> [DllImport("kernel32.dll")]<br> public static extern int GetPrivateProfileString ( string section ,string key , string def , StringBuilder retVal ,int size , string filePath ) ;<br> [DllImport("kernel32")] <br> public static extern long WritePrivateProfileString ( string section,string key,string val,string filePath ) ;<br><br> private System.ComponentModel.IContainer components;<br><br> public static int LocaPort;//本地端口<br> public static string RemoteIp;<br> public static int RemotePort;//远程端口<br> public static string sCompanyName;//公司名称<br><br> private Icon m_Icon1; <br> private Icon m_Icon2;<br> private Icon m_Icon3;<br><br> private NotifyIcon notifyIcon;<br><br> MenuItem menuItem1;<br> MenuItem menuItem2;<br><br> private Hashtable CarID_RemoteIP_Hash;<br><br> private Thread thGprs ;<br> private Thread thTcpMsg ;<br> private Socket socket;<br> private Socket TcpSocket;<br><br> private System.Windows.Forms.Timer TimerIcon;<br> private System.Windows.Forms.Label lblInfo;<br> private System.Windows.Forms.Timer TimerConn;<br> private byte[] TempBuff;<br> private System.Windows.Forms.CheckBox checkBox1;<br> private System.Windows.Forms.ImageList imgList;// = new byte[1024];<br> private byte[] TcpBuff;<br> private System.Windows.Forms.ListView lvwMsg;<br> private System.Windows.Forms.ColumnHeader sId;<br> private System.Windows.Forms.ColumnHeader sNote;<br> private System.Windows.Forms.Button cmdExit;<br> private System.Windows.Forms.Button cmdSet;// = new byte[2048];<br><br> private bool bTsFlag=false;<br> public GprsServer()<br> {<br><br> InitializeComponent();<br> //检测配置文件目录是否存在<br> GetSysPra();<br><br> TempBuff= new byte[1];<br> TcpBuff=new byte[1];<br><br> m_Icon1 = new Icon("SysFile\\Icon1.ico");<br> m_Icon2 = new Icon("SysFile\\Icon2.ico"); <br> m_Icon3 = new Icon("SysFile\\Icon3.ico"); <br><br> notifyIcon = new NotifyIcon(); <br> notifyIcon.Icon = m_Icon1; <br> notifyIcon.Text = sCompanyName; <br> notifyIcon.Visible = true; <br><br> menuItem1=new MenuItem("设置"); <br> menuItem2=new MenuItem("退出"); <br><br> menuItem1.Click+=new EventHandler(this.menuItem1_Click); <br> menuItem2.Click+=new EventHandler(this.menuItem2_Click); <br><br> notifyIcon.ContextMenu=new ContextMenu(new MenuItem[]{menuItem1,menuItem2}); <br> notifyIcon.DoubleClick+=new System.EventHandler(this.notifyIcon_DBClick); <br><br> CarID_RemoteIP_Hash=new Hashtable();<br><br> thGprs = new Thread(new ThreadStart(ReadUdp)) ;<br> //启动线程<br> thGprs.IsBackground =true;//将线程作为后台线程处理,用途,当主线程关闭,子线程随着关闭<br> thGprs.Start( );<br><br> try<br> {<br> IPHostEntry IPHost = Dns.Resolve(RemoteIp);<br> string []aliases = IPHost.Aliases; <br> IPAddress []addr = IPHost.AddressList;<br> EndPoint ep = new IPEndPoint(addr[0],RemotePort); <br> TcpSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);<br> TcpSocket.Connect(ep);<br><br> thTcpMsg = new Thread (new ThreadStart(ReadTcpMsg)) ;<br> //启动线程<br> thTcpMsg.IsBackground =true;<br> thTcpMsg.Start( ) ;<br> lblInfo.Text ="系统运行正常,正在中转GPRS数据...";<br> }<br> catch<br> {}<br> }<br><br> private void GetSysPra()<br> {<br> StringBuilder temp = new StringBuilder(255);<br> if (Directory.Exists("SysIni"))<br> {<br> if (File.Exists("SysIni\\SysIni.ini"))<br> {<br> int i;<br> i= GetPrivateProfileString("PortIni","UdpPort","",temp,255,"SysIni\\SysIni.ini");<br> if (i==0)<br> {<br> LocaPort=8888;<br> WritePrivateProfileString("PortIni","UdpPort","8888","SysIni\\SysIni.ini");<br> }<br> else<br> {<br> LocaPort=int.Parse(temp.ToString( ));<br> }<br> i = GetPrivateProfileString("Company","Name","",temp,255,"SysIni\\SysIni.ini");<br> if (i==0)<br> {<br> sCompanyName="龙翰科技";<br> WritePrivateProfileString("Company","Name","龙翰科技","SysIni\\SysIni.ini");<br> }<br> else<br> {<br> sCompanyName=temp.ToString( );<br> }<br> i = GetPrivateProfileString("PortIni","TcpAddress","",temp,255,"SysIni\\SysIni.ini");<br> if (i==0)<br> {<br> RemoteIp="127.0.0.1";<br> WritePrivateProfileString("PortIni","TcpAddress","127.0.0.1","SysIni\\SysIni.ini");<br> }<br> else<br> {<br> RemoteIp=temp.ToString( );<br> }<br> i = GetPrivateProfileString("PortIni","TcpPort","",temp,255,"SysIni\\SysIni.ini");<br> if (i==0)<br> {<br> RemotePort=6666;<br> WritePrivateProfileString("PortIni","TcpPort","6666","SysIni\\SysIni.ini");<br> }<br> else<br> {<br> RemotePort=int.Parse(temp.ToString( ));<br> }<br> }<br> else<br> {<br> //File.Create("SysIni\\SysIni.ini",255);<br> LocaPort=8888;<br> WritePrivateProfileString("PortIni","UdpPort","8888","SysIni\\SysIni.ini");<br> sCompanyName="龙翰科技";<br> WritePrivateProfileString("Company","Name","龙翰科技","SysIni\\SysIni.ini");<br> RemoteIp="127.0.0.1";<br> WritePrivateProfileString("PortIni","TcpAddress","127.0.0.1","SysIni\\SysIni.ini");<br> RemotePort=6666;<br> WritePrivateProfileString("PortIni","TcpPort","6666","SysIni\\SysIni.ini");<br> }<br> }<br> else<br> {<br> Directory.CreateDirectory("SysIni");<br> //File.Create("SysIni\\SysIni.ini",255);<br> LocaPort=8888;<br> WritePrivateProfileString("PortIni","UdpPort","8888","SysIni\\SysIni.ini");<br> sCompanyName="龙翰科技";<br> WritePrivateProfileString("Company","Name","龙翰科技","SysIni\\SysIni.ini");<br> RemoteIp="127.0.0.1";<br> WritePrivateProfileString("PortIni","TcpAddress","127.0.0.1","SysIni\\SysIni.ini");<br> RemotePort=6666;<br> WritePrivateProfileString("PortIni","TcpPort","6666","SysIni\\SysIni.ini");<br> }<br> }<br> /// <summary><br> /// 清理所有正在使用的资源。<br> /// </summary><br> <br> private void menuItem1_Click(object sender,System.EventArgs e)<br> { <br> //<br> } <br> private void menuItem2_Click(object sender,System.EventArgs e)<br> { <br> this.Close(); <br> Application.Exit(); <br> } <br> private void notifyIcon_DBClick(object sender, System.EventArgs e)<br> {<br> //<br> }<br><br> protected override void Dispose( bool disposing )<br> {<br> if( disposing )<br> {<br> if (components != null) <br> {<br> components.Dispose();<br> }<br> notifyIcon.Visible =false;; <br> notifyIcon.Icon=null;<br> notifyIcon.Dispose();<br> m_Icon1.Dispose();<br> m_Icon2.Dispose();<br> m_Icon3.Dispose();<br> }<br> base.Dispose( disposing );<br> }<br><br> #region Windows 窗体设计器生成的代码<br> /// <summary><br> /// 设计器支持所需的方法 - 不要使用代码编辑器修改<br> /// 此方法的内容。<br> /// </summary><br> private void InitializeComponent()<br> {<br> this.components = new System.ComponentModel.Container();<br> System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(GprsServer));<br> this.TimerIcon = new System.Windows.Forms.Timer(this.components);<br> this.lblInfo = new System.Windows.Forms.Label();<br> this.TimerConn = new System.Windows.Forms.Timer(this.components);<br> this.lvwMsg = new System.Windows.Forms.ListView();<br> this.sId = new System.Windows.Forms.ColumnHeader();<br> this.sNote = new System.Windows.Forms.ColumnHeader();<br> this.imgList = new System.Windows.Forms.ImageList(this.components);<br> this.checkBox1 = new System.Windows.Forms.CheckBox();<br> this.cmdExit = new System.Windows.Forms.Button();<br> this.cmdSet = new System.Windows.Forms.Button();<br> this.SuspendLayout();<br> // <br> // TimerIcon<br> // <br> this.TimerIcon.Enabled = true;<br> this.TimerIcon.Interval = 1000;<br> this.TimerIcon.Tick += new System.EventHandler(this.TimerIcon_Tick);<br> // <br> // lblInfo<br> // <br> this.lblInfo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;<br> this.lblInfo.Location = new System.Drawing.Point(4, 298);<br> this.lblInfo.Name = "lblInfo";<br> this.lblInfo.Size = new System.Drawing.Size(310, 23);<br> this.lblInfo.TabIndex = 0;<br> this.lblInfo.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;<br> // <br> // TimerConn<br> // <br> this.TimerConn.Enabled = true;<br> this.TimerConn.Interval = 6000;<br> this.TimerConn.Tick += new System.EventHandler(this.TimerConn_Tick);<br> // <br> // lvwMsg<br> // <br> this.lvwMsg.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {<br> this.sId,<br> this.sNote});<br> this.lvwMsg.FullRowSelect = true;<br> this.lvwMsg.Location = new System.Drawing.Point(2, 2);<br> this.lvwMsg.Name = "lvwMsg";<br> this.lvwMsg.Size = new System.Drawing.Size(564, 292);<br> this.lvwMsg.SmallImageList = this.imgList;<br> this.lvwMsg.TabIndex = 1;<br> this.lvwMsg.View = System.Windows.Forms.View.Details;<br> // <br> // sId<br> // <br> this.sId.Text = "";<br> this.sId.Width = 21;<br> // <br> // sNote<br> // <br> this.sNote.Text = "消息内容";<br> this.sNote.Width = 522;<br> // <br> // imgList<br> // <br> this.imgList.ColorDepth = System.Windows.Forms.ColorDepth.Depth16Bit;<br> this.imgList.ImageSize = new System.Drawing.Size(16, 16);<br> this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream")));<br> this.imgList.TransparentColor = System.Drawing.Color.Transparent;<br> // <br> // checkBox1<br> // <br> this.checkBox1.FlatStyle = System.Windows.Forms.FlatStyle.Popup;<br> this.checkBox1.Location = new System.Drawing.Point(332, 300);<br> this.checkBox1.Name = "checkBox1";<br> this.checkBox1.Size = new System.Drawing.Size(104, 19);<br> this.checkBox1.TabIndex = 2;<br> this.checkBox1.Text = "显示调试数据";<br> this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);<br> // <br> // cmdExit<br> // <br> this.cmdExit.FlatStyle = System.Windows.Forms.FlatStyle.Popup;<br> this.cmdExit.Location = new System.Drawing.Point(504, 298);<br> this.cmdExit.Name = "cmdExit";<br> this.cmdExit.Size = new System.Drawing.Size(60, 22);<br> this.cmdExit.TabIndex = 3;<br> this.cmdExit.Text = "退出(&E)";<br> this.cmdExit.Click += new System.EventHandler(this.cmdExit_Click);<br> // <br> // cmdSet<br> // <br> this.cmdSet.FlatStyle = System.Windows.Forms.FlatStyle.Popup;<br> this.cmdSet.Location = new System.Drawing.Point(432, 298);<br> this.cmdSet.Name = "cmdSet";<br> this.cmdSet.Size = new System.Drawing.Size(60, 22);<br> this.cmdSet.TabIndex = 4;<br> this.cmdSet.Text = "设置(&S)";<br> this.cmdSet.Click += new System.EventHandler(this.cmdSet_Click);<br> // <br> // GprsServer<br> // <br> this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);<br> this.ClientSize = new System.Drawing.Size(566, 323);<br> this.Controls.Add(this.cmdSet);<br> this.Controls.Add(this.cmdExit);<br> this.Controls.Add(this.checkBox1);<br> this.Controls.Add(this.lvwMsg);<br> this.Controls.Add(this.lblInfo);<br> this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;<br> this.MaximizeBox = false;<br> this.Name = "GprsServer";<br> this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;<br> this.Text = "中继服务器";<br> this.Load += new System.EventHandler(this.GprsServer_Load);<br> this.ResumeLayout(false);<br><br> }<br> #endregion<br><br> /// <summary><br> /// 应用程序的主入口点。<br> /// </summary><br> [STAThread]<br> static void Main() <br> {<br> Application.Run(new GprsServer());<br> }<br><br> private byte Get_CheckXor(ref byte[] temp,int len)<br> {<br> byte A=0;<br> for(int i=0;i<len;i++)<br> {<br> A^=temp[i];<br> }<br> return A;<br> }<br><br> private void ReadTcpMsg() //读取用户发送的指令数据<br> {<br> byte[] buff= new byte[2048];<br> string CartIpAddress="";//车辆的IP地址<br> EndPoint TempRemote = null;<br><br> int recv = 0;<br> byte[] Tbuff;<br> byte[] AllBuff;<br> int iLenght=0;<br> int iIndex=0;<br> int iLen=0;<br> int iXorValue=0;<br><br> while(true)<br> {<br> try<br> {<br> recv=TcpSocket.Receive(buff,0,TcpSocket.Available,SocketFlags.None);//读取数据内容<br> if (recv==0)<br> {<br> recv=TcpSocket.Receive(buff,0,TcpSocket.Available,SocketFlags.None);//读取数据内容<br> if (recv==0)<br> {<br> TcpSocket.Close();<br> break;<br> }<br> }<br><br> }<br> catch<br> {<br> break;<br> }<br><br> AllBuff=new byte[recv +TcpBuff.Length];<br> for (iIndex = 1; iIndex <=TcpBuff.Length; iIndex++)<br> {<br> AllBuff[iIndex-1]=TcpBuff[iIndex-1];<br> }<br><br> for (iIndex = 1; iIndex <=recv; iIndex++)<br> {<br> AllBuff[TcpBuff.Length+iIndex-1]=buff[iIndex-1];<br> }<br><br> for (iIndex = 1; iIndex <=AllBuff.Length; iIndex++)<br> {<br> iLenght=AllBuff.Length-iIndex+1;<br> if (iLenght<6)//检测数据包长度<br> {<br> //不完整,则将指令保存<br> if (iLenght>0)<br> {<br> TcpBuff=new byte[iLenght];<br> for (iLen = 1; iLen <=iLenght; iLen++)<br> {<br> TcpBuff[iLen-1]=AllBuff[iLen+iIndex-2];<br> }<br> }<br> break;<br> }<br> else<br> {<br> //检测当前指令是否是完整的指令,查找数据包头<br> if (AllBuff[iIndex-1]==0x29 & AllBuff[iIndex]==0x29)<br> {<br> if ((AllBuff.Length -iIndex)>=(AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4))<br> {<br> //检测当前指令是否是完整的指令<br> if ((AllBuff[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+iIndex+3])==0x0D)<br> {<br> //在接收的数据中获取单条完整的指令数据<br> Tbuff=new byte[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+5];<br> for (iLen = 1; iLen <=Tbuff.Length; iLen++)<br> {<br> Tbuff[iLen-1]=AllBuff[iLen+iIndex-2];<br> }<br> iXorValue=Get_CheckXor(ref Tbuff,Tbuff.Length-2);<br> if(iXorValue!=Tbuff[Tbuff.Length-2])<br> {<br> //校验不合格,继续查找合法指令数据<br> continue;<br> }<br> else<br> {<br> if (bTsFlag)<br> {<br> string BuffToStr="";<br> for(int i=0;i<Tbuff.Length;i++)<br> {<br> BuffToStr+=Tbuff[i].ToString("X2")+" ";<br> }<br> ShowSysMsg(BuffToStr,2);<br> }<br> //获取车载终端手机号<br> CartIpAddress=Tbuff[5]+"." +Tbuff[6] +"."+Tbuff[7] +"."+Tbuff[8];<br> TempRemote=(EndPoint)CarID_RemoteIP_Hash[CartIpAddress];<br> if( TempRemote==null)<br> {<br> if (bTsFlag)<br> {<br> ShowSysMsg("无法查找到接收数据的远程终节点!",3);<br> }<br> }<br> else<br> {<br> try<br> {<br> socket.SendTo(Tbuff,TempRemote);<br> if (bTsFlag)<br> {<br> ShowSysMsg("数据成功转发到车载终端!",1);<br> }<br> }<br> catch<br> {<br> if (bTsFlag)<br> {<br> ShowSysMsg("数据转发到车载终端失败!",3);<br> }<br> }<br> } <br> iIndex=iIndex+Tbuff.Length-1;<br> TcpBuff=new byte[1];<br> }<br> }<br> else<br> {<br> continue;<br> }<br> }<br> else<br> {<br> if ((AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4)>1024)<br> {<br> continue;<br> }<br> else<br> {<br> //不完整,则将指令保存<br> if (iLenght>0)<br> {<br> TcpBuff=new byte[iLenght];<br> for (iLen = 1; iLen <=iLenght; iLen++)<br> {<br> TcpBuff[iLen-1]=AllBuff[iLen+iIndex-2];<br> }<br> break;<br> }<br> else<br> {<br> TcpBuff=new byte[1];<br> break;<br> }<br><br> }<br> }<br> }<br> else<br> {<br> continue;<br> }<br> }//检测数据包长度<br> }<br> }<br> }<br><br> public void ShowSysMsg(string sNote,int iIcon)<br> {<br> //显示系统消息<br> try<br> {<br> lvwMsg.BeginUpdate();<br> if (lvwMsg.Items.Count >100)<br> lvwMsg.Items.Clear();<br> ListViewItem li = new ListViewItem();<br> //li.SubItems[0].Text =sNote ;<br> li.SubItems.Add (sNote);<br> li.ImageIndex=iIcon;<br> lvwMsg.Items.Add(li);<br> lvwMsg.EndUpdate();<br> }<br> catch<br> {}<br> }<br><br> private void ReadUdp() //从UDP数据端口读取GPRS数据<br> {<br> byte[] buff = new byte[1024];<br> int recv = 0;<br> byte[] Tbuff;<br> byte[] AllBuff;<br> int iLenght=0;<br> int iIndex=0;<br> int iLen=0;<br> int iXorValue=0;<br> string CarIpAddress="";<br> byte[] RecvAffirmBuff=new byte[]{0x29,0x29,0x21,0x00,0x05,0,0,0,0,0x0D};//回应终端数组<br><br> IPEndPoint ipep = new IPEndPoint(IPAddress.Any ,LocaPort); <br> //socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);<br> socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);<br> try<br> {<br> socket.Bind(ipep);<br> ShowSysMsg("系统成功在"+LocaPort + "端口侦听!",6);<br> }<br> catch<br> {<br> ShowSysMsg("端口"+LocaPort+"已被占用,系统侦听失败!",5);<br> return;<br> }<br> IPEndPoint sender = new IPEndPoint(IPAddress.Any , 0);//指远程终端(终节点)Ip地址对象 IPAddress.Any表示任何地址 0 表示任何端口<br> EndPoint remote = (EndPoint)(sender); //指远程终端(终节点)<br><br> while(true)<br> {<br> try<br> {<br> recv = socket.ReceiveFrom(buff , ref remote);<br> }<br> catch<br> {<br> ShowSysMsg("接收车载终端数据错误!",3);<br> }<br> //---------------------you2004-12-31 begin------------------------------//<br> AllBuff=new byte[recv +TempBuff.Length];<br> for (iIndex = 1; iIndex <=TempBuff.Length; iIndex++)<br> {<br> AllBuff[iIndex-1]=TempBuff[iIndex-1];<br> }<br><br> for (iIndex = 1; iIndex <=recv; iIndex++)<br> {<br> AllBuff[TempBuff.Length+iIndex-1]=buff[iIndex-1];<br> }<br><br> for (iIndex = 1; iIndex <=AllBuff.Length; iIndex++)<br> {<br> iLenght=AllBuff.Length-iIndex+1;<br> if (iLenght<6)//检测数据包长度<br> {<br> //不完整,则将指令保存<br> if (iLenght>0)<br> {<br> TempBuff=new byte[iLenght];<br> for (iLen = 1; iLen <=iLenght; iLen++)<br> {<br> TempBuff[iLen-1]=AllBuff[iLen+iIndex-2];<br> }<br> }<br> break;<br> }<br> else<br> {<br> //检测当前指令是否是完整的指令,查找数据包头<br> if (AllBuff[iIndex-1]==0x29 & AllBuff[iIndex]==0x29)<br> {<br> if ((AllBuff.Length -iIndex)>=(AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4))<br> {<br> //检测当前指令是否是完整的指令<br> if ((AllBuff[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+iIndex+3])==0x0D)<br> {<br> //在接收的数据中获取单条完整的指令数据<br> Tbuff=new byte[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+5];<br> for (iLen = 1; iLen <=Tbuff.Length; iLen++)<br> {<br> Tbuff[iLen-1]=AllBuff[iLen+iIndex-2];<br> }<br> iXorValue=Get_CheckXor(ref Tbuff,Tbuff.Length-2);<br> if(iXorValue!=Tbuff[Tbuff.Length-2])<br> {<br> //校验不合格,继续查找合法指令数据<br> continue;<br> }<br> else<br> {<br> if (bTsFlag)<br> {<br> string BuffToStr="";<br> for(int i=0;i<Tbuff.Length;i++)<br> {<br> BuffToStr+=Tbuff[i].ToString("X2")+" ";<br> }<br> ShowSysMsg(BuffToStr,0);<br> }<br><br> //获取车载终端手机号<br> CarIpAddress=Tbuff[5]+"." +Tbuff[6] +"."+Tbuff[7] +"."+Tbuff[8];<br> <br> //-----------------检测系统哈希表是否包含此终端数据---------------------\\<br> if(CarID_RemoteIP_Hash.ContainsKey(CarIpAddress))<br> {<br> CarID_RemoteIP_Hash[CarIpAddress]=remote;//有更新<br> }<br> else<br> {<br> CarID_RemoteIP_Hash.Add(CarIpAddress,remote);//没有添加<br> }<br><br> //--------------------将数据转发到中心处理程序-----------------\\<br> if (TcpSocket.Connected)<br> {<br> try<br> {<br> TcpSocket.Send(Tbuff,0,Tbuff.Length,SocketFlags.None);<br> if (bTsFlag)<br> {<br> ShowSysMsg("数据成功转发到网络中心处理程序!",1);<br> }<br> }<br> catch<br> {<br> if (bTsFlag)<br> {<br> ShowSysMsg("数据转发到网络中心处理程序失败!",3);<br> }<br> }<br> }<br> //-------------------向终端发出0x21的接收确认-------------------\\<br> RecvAffirmBuff[5]=Tbuff[Tbuff.Length-2];<br> RecvAffirmBuff[6]=Tbuff[2];<br> RecvAffirmBuff[7]=Tbuff[9];<br> RecvAffirmBuff[8]=Get_CheckXor(ref RecvAffirmBuff,8);<br> socket.SendTo(RecvAffirmBuff,remote);<br> iIndex=iIndex+Tbuff.Length-1;<br> TempBuff=new byte[1];<br> }<br> }<br> else<br> {<br> continue;<br> }<br> }<br> else<br> {<br> if ((AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4)>1024)<br> {<br> continue;<br> }<br> else<br> {<br> //不完整,则将指令保存<br> if (iLenght>0)<br> {<br> TempBuff=new byte[iLenght];<br> for (iLen = 1; iLen <=iLenght; iLen++)<br> {<br> TempBuff[iLen-1]=AllBuff[iLen+iIndex-2];<br> }<br> break;<br> }<br> else<br> {<br> TempBuff=new byte[1];<br> break;<br> }<br><br> }<br> }<br> }<br> else<br> {<br> continue;<br> }<br> }//检测数据包长度<br> <br> }<br> //---------------------you2004-12-31 end------------------------------//<br> }<br><br> }<br><br> private void GprsServer_Load(object sender, System.EventArgs e)<br> {<br> //<br> }<br><br> int I=0;<br> private void TimerIcon_Tick(object sender, System.EventArgs e)<br> {<br> if(thGprs!=null)<br> { <br> if(thGprs.IsAlive)<br> notifyIcon.Icon=notifyIcon.Icon==m_Icon1?m_Icon2:m_Icon1;<br> else<br> notifyIcon.Icon=notifyIcon.Icon==m_Icon1?m_Icon3:m_Icon1;<br> }<br> I++;<br> if(I>5)<br> {<br> I=FindWindow(null,@sCompanyName);<br> if( I!= 0)<br> {<br> SendMessage(I,0x501,1002,"");<br> }<br> I=0;<br> } <br> }<br><br> private void TimerConn_Tick(object sender, System.EventArgs e)<br> {<br> if (!TcpSocket.Connected)<br> {<br> try<br> {<br> lblInfo.Text ="与中心数据处理程序断开,正在进行二次连接...";<br> IPHostEntry IPHost = Dns.Resolve(RemoteIp);<br> string []aliases = IPHost.Aliases; <br> IPAddress []addr = IPHost.AddressList;<br> EndPoint ep = new IPEndPoint(addr[0],RemotePort); <br> TcpSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);<br> TcpSocket.Connect(ep);<br><br> thTcpMsg = new Thread ( new ThreadStart(ReadTcpMsg)) ;<br> //启动线程<br> thTcpMsg.IsBackground =true;<br> thTcpMsg.Start( ) ;<br> lblInfo.Text ="系统运行正常,正在中转GPRS数据...";<br> }<br> catch<br> {<br> return;<br> }<br> }<br> }<br><br> private void checkBox1_CheckedChanged(object sender, System.EventArgs e)<br> {<br> bTsFlag=checkBox1.Checked;<br> }<br><br> private void cmdExit_Click(object sender, System.EventArgs e)<br> {<br> if(MessageBox.Show("确定关闭中继服务器?", "提示",MessageBoxButtons.YesNo,MessageBoxIcon.Information) == DialogResult.Yes)<br> {<br> Application.Exit ();<br> }<br> }<br><br> private void cmdSet_Click(object sender, System.EventArgs e)<br> {<br> frmUdpSet frmudpset=new frmUdpSet();<br> frmudpset.Show();<br> }<br> <br> protected override void OnClosing(CancelEventArgs e)<br> {<br> e.Cancel =true;<br> this.WindowState =FormWindowState.Minimized;<br> }<br> }<br>}<br>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值