网络游戏的封包技术是大多数编程爱好者都比较关注的关注的问题之一,在这里就让我们一起研究一下这一个问题吧。
别看这是封包这一问题,但是涉及的技术范围很广范,实现的方式也很多(比如说apihook,vxd,winsock2都可以实现),在这里我们不可能每种技术和方法都涉及,所以我在这里以winsock2技术作详细讲解,就算作抛砖引玉。
由于大多数读者对封包类编程不是很了解,我在这里就简单介绍一下相关知识:
apihook:
由于windows的把内核提供的功能都封装到api里面,所以大家要实现功能就必须通过api,换句话说就是我们要想捕获数据封包,就必须先要得知道并且捕获这个api,从api里面得到封包信息。
vxd:
直接通过控制vxd驱动程序来实现封包信息的捕获,不过vxd只能用于win9x。
winsock2:
winsock是windows网络编程接口,winsock工作在应用层,它提供与底层传输协议无关的高层数据传输编程接口,winsock2是winsock2.0提供的服务提供者接口,但只能在win2000下用。
好了,我们开始进入winsock2封包式编程吧。
在封包编程里面我准备分两个步骤对大家进行讲解:1、封包的捕获,2、封包的发送。
首先我们要实现的是封包的捕获:
delphi的封装的winsock是1.0版的,很自然winsock2就用不成。如果要使用winsock2我们要对winsock2在delphi里面做一个接口,才可以使用winsock2。
1、如何做winsock2的接口?
1)我们要先定义winsock2.0所用得到的类型,在这里我们以wsa_data类型做示范,大家可以举一仿三的来实现winsock2其他类型的封装。
我们要知道wsa_data类型会被用于wsastartup(wversionrequired: word; var wsdata: twsadata): integer;,大家会发现wsdata是引用参数,在传入参数时传的是变量的地址,所以我们对wsa_data做以下封装:
| const wsadescription_len = 256; wsasys_status_len = 128; type pwsa_data = ^twsa_data; wsa_data = record wversion: word; whighversion: word; szdescription: array[0..wsadescription_len] of char; szsystemstatus: array[0..wsasys_status_len] of char; imaxsockets: word; imaxudpdg: word; lpvendorinfo: pchar; end; twsa_data = wsa_data; |
| function wsastartup(wversionrequired: word; var wsdata: twsadata): integer; stdcall; implementation const winsocket2 = 'ws2_32.dll'; function wsastartup; external winsocket name 'wsastartup'; |
| integer wsastartup( wversionrequired: word, wsdata: twsa_data ); |
| integer socket(af: integer, struct: integer, protocol: integer ); m_hsocket:=socket(af_.net, sock_raw, ipproto_ip); |
| type in_addr = record s_addr : pchar; end; type tsock_addr = record sin_family: word; sin_port: word; sin_addr : in_addr sin_zero: array[0..7] of char; end; var localaddr:tsock_addr; localaddr.sin_family: = af_.net; localaddr.sin_port: = 0; localaddr.sin_addr.s_addr: = .net_addr('192.168.1.1'); //这里你自己的网卡的ip地址,而.net_addr这个函数是winsock2的函数。 bind(m_hsocket, localaddr, sizeof(localaddr)); |
| integer wsaioctl(s:integer, dwiocontrolcode : integer, lpvinbuffer :integer, cbinbuffer : integer, lpvoutbuffer : integer, cboutbuffer: integer, lpcbbytesreturned : integer, lpoverlapped : integer, lpcompletionroutine : integer ); |
| integer recv (s : integer, buffer:array[0..4095] of byte, length : integer, flags : integer, ); |
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器