下面是我写的一个自动NAT的delphi控件,楼主自己琢磨吧:<br>unit AutoNAT;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Scktcomp, NMUDP, extctrls;<br><br>//<br>// 定义事件类...<br>type<br> TTaskSuccessEvent = procedure (Sender: TObject) of object; {任务执行成功事件}<br> TTaskFailEvent = procedure (Sender: TObject) of object; {任务执行失败事件}<br><br>type<br> TAutoNAT = class(TComponent)<br> private<br>//<br>// 只读属性...<br> fTimeout: integer; {任务超时值}<br> fTaskType: integer; {任务列别: 1-搜索 2-取控制页地址 3-增加端口 4-取外网地址 5-删除端口}<br> fLocalIp: string; {本机内网IP}<br> fRouterIp: string; {路由器内网IP}<br> fRouterPort: integer; {路由器控制端口}<br> fRouterLocation: string; {路由器设备位置URL}<br> fRouterName: string; {路由器设备名称}<br> fRouterUSN: string; {路由器设备标识名}<br> fRouterURL: string; {路由器URL}<br> fExternalIp: string; {路由器外网IP}<br> fControlURL: string; {控制页URL}<br> fURLbase: string; {控制页基地址}<br>//<br>// 事件...<br> FOnTaskSuccess: TNotifyEvent; {任务执行成功的事件}<br> FOnTaskFail: TNotifyEvent; {任务执行失败的事件}<br>//<br>// 普通变量...<br> request: string; {socket请求数据包}<br> requested: boolean; {请求是否已发送}<br> response: string; {socket应答数据包}<br> //<br> UDP: TNMUDP; {UDP对象}<br> Sock: TClientSocket; {Socket对象}<br> TaskTimer: TTimer; {任务定时器}<br> //<br> TaskExecuting: boolean; {当前是否有任务在执行}<br> Taskfinished: boolean; {任务是否已经完成}<br> Tasksuccess: boolean; {任务是否成功}<br>//<br>// 其它私有过程...<br> procedure SetTimeout(Timeout: integer);<br> procedure SuccessEvent;<br> procedure FailEvent;<br> procedure TaskTimerTimer(Sender: TObject); {超时事件}<br> procedure UDPInvalidHost(var handled: Boolean); {主机无效时的事件}<br> procedure UDPBufferInvalid(var handled: Boolean; var Buff: array of Char; var length: Integer);<br> procedure UDPStreamInvalid(var handled: Boolean; Stream: TStream);<br> procedure UDPDataReceived(Sender: TComponent; NumberBytes: Integer; FromIP: String; Port: Integer);<br> procedure ClientSocketWrite(Sender: TObject; Socket: TCustomWinSocket);<br> procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);<br> function ResponseFinished(ResponseData: string): boolean;<br> procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);<br> procedure ClientSocketDisconnect(Sender: TObject; Socket: TCustomWinSocket);<br>//<br> protected<br> { Protected declarations }<br><br> public<br> //<br> // 创建对象...<br> Constructor Create(AOwner: TComponent); override; {对象创建时的方法}<br> //<br> // 撤消对象...<br> Destructor Destroy(); override; {对象撤消的方法}<br> //<br> // 搜索路由器设备(任务1)...<br> function SearchRouter(): boolean;<br> //<br> // 得到路由器控制页{任务2}...<br> function GetControlURL(): boolean;<br> //<br> // 增加端口映射项(任务3)...<br> function AddNatMapping(NatPortName: string; ExternalPort: integer; LocalIp: string; LocalPort: integer; Protocol: string): boolean;<br> //<br> // 取外网IP地址(任务4)...<br> function GetExternalIp: boolean;<br> //<br> // 删除端口映射项(任务5)...<br> function DeleteNatMapping(ExternalPort: integer; Protocol: string): boolean;<br> //<br> published<br> //<br> // 控件属性...<br> property Timeout: integer read fTimeout write settimeout; {任务超时值}<br> property TaskType: integer read fTaskType; {任务列别: 1-搜索 2-取控制页地址 3-增加端口 4-取外网地址 5-删除端口}<br> property LocalIp: string read fLocalIp; {本机内网IP}<br> property RouterIp: string read fRouterIp; {路由器内网IP}<br> property RouterPort: integer read fRouterPort; {路由器控制端口}<br> property RouterLocation: string read fRouterLocation; {路由器设备位置URL}<br> property RouterName: string read fRouterName; {路由器设备名称}<br> property RouterUSN: string read fRouterUSN; {路由器设备标识名}<br> property RouterURL: string read fRouterURL; {路由器URL}<br> property ExternalIp: string read fExternalIp; {路由器外网IP}<br> property ControlURL: string read fControlURL; {控制页URL}<br> property URLBase: string read fURLBase; {基地址}<br> //<br> // 事件...<br> property OnTaskSuccess: TNotifyEvent read FOnTaskSuccess write FOnTaskSuccess; {任务执行成功的事件}<br> property OnTaskFail: TNotifyEvent read FOnTaskFail write FOnTaskFail; {任务执行失败的事件}<br> //<br> end;<br><br>procedure Register;<br><br>implementation<br><br>//<br>// 控件注册的过程...<br>procedure Register;<br>begin<br> RegisterComponents('AutoNAT', [TAutoNAT]);<br>end;<br><br>//<br>// 创建对象的过程...<br>constructor TAutoNAT.Create(AOwner: TComponent);<br>begin<br>//<br>// 调用TComponent的方法,创建...<br> inherited;<br>//<br>// 创建内部变量...<br> UDP:=TNMUDP.Create(self); {UDP对象}<br> udp.RemoteHost:='239.255.255.250'; {广播地址}<br> udp.RemotePort:=1900; {广播端口} <br> udp.LocalPort:=1900;<br> UDP.OnInvalidHost:=UDPInvalidHost; {主机无效事件}<br> UDP.OnBufferInvalid:=UDPBufferInvalid; {缓冲区无效事件}<br> UDP.OnStreamInvalid:=UDPStreamInvalid; {流无效事件}<br> UDP.OnDataReceived:=UDPDataReceived; {收到应答数据时的事件}<br> //<br> sock:=TClientSocket.create(self); {ClientSocket对象}<br> sock.ClientType:=ctNonBlocking; {非阻塞型}<br> sock.OnWrite:=clientsocketwrite; {提交请求事件}<br> sock.OnRead:=clientsocketread; {应答响应事件}<br> sock.OnError:=clientsocketerror; {异常事件}<br> sock.OnDisconnect:=clientsocketdisconnect; {断开事件}<br> //<br> TaskTimer:=TTimer.Create(self); {超时定时器}<br> TaskTimer.Interval:=1000*5; {默认5秒超时}<br> TaskTimer.enabled:=false; {不激活定时器}<br> TaskTimer.OnTimer:=TaskTimerTimer; {指定超时处理事件}<br> //<br> taskexecuting:=false; {没有任务在执行}<br> taskfinished:=false; {未完成}<br> tasksuccess:=false; {未成功}<br> //<br> fexternalip:='0.0.0.0'; {外网IP暂时未知}<br> ftimeout:=5000; {默认超时值=5秒}<br>end;<br><br>//<br>// 撤消对象的过程...<br>destructor TAutoNAT.Destroy;<br>begin<br>//<br>// 释放对象...<br> UDP.free;<br> tasktimer.free;<br> sock.free;<br>//<br>// 调用TComponent的方法,撤消...<br> inherited;<br>end;<br><br>//<br>// 设置任务超时值的过程...<br>procedure TAutoNAT.SetTimeout(Timeout: integer);<br>begin<br> if (timeout<1000) or (timeout>30*1000) then<br> begin<br> messagebox(0,'对不起,超时值范围1000-30000,重新输入!','提示',mb_ok+mb_iconinformation);<br> exit;<br> end;<br> ftimeout:=timeout;<br>end;<br><br>//<br>// 激发一个成功事件的过程...<br>procedure TAutoNAT.SuccessEvent;<br>begin<br> tasktimer.enabled:=false;<br>//<br>// 设置任务已经完成...<br> taskexecuting:=false; {任务不在执行了}<br> taskfinished:=true; {任务已经完成}<br> tasksuccess:=true; {任务成功}<br>//<br>// 激发一个成功事件...<br> if assigned(fontasksuccess) then<br> fontasksuccess(self);<br>end;<br><br>//<br>// 激发一个失败事件的过程...<br>procedure TAutoNAT.FailEvent;<br>begin<br> tasktimer.enabled:=false;<br>//<br>// 设置任务已经完成...<br> taskexecuting:=false; {任务不在执行了}<br> taskfinished:=true; {任务已经完成}<br> tasksuccess:=false; {任务失败}<br>//<br>// 激发一个失败事件...<br> if assigned(fontaskfail) then<br> fontaskfail(self);<br>end;<br><br>//<br>// UDP的主机无效事件...<br>procedure TAutoNAT.UDPInvalidHost(var handled: Boolean);<br>begin<br> failevent; {激发失败事件}<br> handled:=true;<br>end;<br><br>//<br>// UDP的缓冲区无效事件...<br>procedure TAutoNAT.UDPBufferInvalid(var handled: Boolean; var Buff: array of Char; var length: Integer);<br>begin<br> failevent; {激发失败事件}<br> handled:=true;<br>end;<br><br>//<br>// UDP的流无效事件...<br>procedure TAutoNAT.UDPStreamInvalid(var handled: Boolean; Stream: TStream);<br>begin<br> failevent; {激发失败事件}<br> handled:=true;<br>end;<br><br>//<br>// 数据到达事件(搜索设备的应答)...<br>procedure TAutoNAT.UDPDataReceived(Sender: TComponent; NumberBytes: Integer; FromIP: String; Port: Integer);<br>var<br> tmpstr: string;<br> buffer: array [0..4096] of char;<br> j: integer;<br>begin<br>//<br>// 无效数据,丢弃...<br> if (numberbytes<=0) or (numberbytes>4096) then<br> exit;<br>//<br>// 读取数据...<br> udp.ReadBuffer(buffer,numberbytes);<br> setlength(tmpstr,numberbytes);<br> strlcopy(pchar(tmpstr),buffer,numberbytes);<br>//<br>// 如果不是有效数据,丢弃...<br> if uppercase(copy(tmpstr,1,5))<>'HTTP/' then<br> begin<br> //<br> // 激发一个任务失败事件...<br> if ftasktype=1 then<br> failevent; {激发失败事件}<br> exit;<br> end;<br>//<br>// 得到Location...<br> fRouterLocation:=tmpstr;<br> j:=pos('LOCATION:',uppercase(fRouterLocation));<br> if j<0 then<br> fRouterLocation:=''<br> else<br> begin<br> delete(fRouterLocation,1,j+8);<br> j:=pos(#13#10,fRouterLocation);<br> fRouterLocation:=trim(copy(fRouterLocation,1,j-1));<br> end;<br>//<br>// 得到Server...<br> fRouterName:=tmpstr;<br> j:=pos('SERVER:',uppercase(fRouterName));<br> if j<0 then<br> fRouterName:=''<br> else<br> begin<br> delete(fRouterName,1,j+6);<br> j:=pos(#13#10,fRouterName);<br> fRouterName:=trim(copy(fRouterName,1,j-1));<br> end;<br>//<br>// 得到USN...<br> fRouterUSN:=tmpstr;<br> j:=pos('USN:',uppercase(fRouterUSN));<br> if j<0 then<br> fRouterUSN:=''<br> else<br> begin<br> delete(fRouterUSN,1,j+3);<br> j:=pos(#13#10,fRouterUSN);<br> fRouterUSN:=trim(copy(fRouterUSN,1,j-1));<br> end;<br>//<br>// 得到路由器IP地址...<br> tmpstr:=fRouterLocation;<br> if copy(uppercase(tmpstr),1,7)='HTTP://' then<br> delete(tmpstr,1,7);<br> j:=pos(':',tmpstr);<br> if j<=0 then<br> begin<br> //<br> // 激发一个任务失败事件...<br> if ftasktype=1 then<br> failevent; {激发失败事件}<br> exit;<br> end;<br> fRouterIp:=copy(tmpstr,1,j-1);<br> delete(tmpstr,1,j);<br>//<br>// 得到路由器端口、控制页URL地址...<br> j:=pos('/',tmpstr);<br> if j>1 then<br> begin<br> try<br> fRouterPort:=strtoint(copy(tmpstr,1,j-1));<br> except<br> fRouterPort:=-1;<br> end;<br> delete(tmpstr,1,j-1);<br> fRouterURL:=tmpstr;<br> end<br> else<br> begin<br> j:=pos(#13#10,tmpstr);<br> if j<=1 then<br> begin<br> //<br> // 激发一个任务失败事件...<br> if ftasktype=1 then<br> failevent; {激发失败事件}<br> exit;<br> end;<br> try<br> fRouterPort:=strtoint(copy(tmpstr,1,j-1));<br> except<br> fRouterPort:=-1;<br> end;<br> fRouterURL:='/';<br> end;<br>//<br>// 得到默认的URLBase...<br> tmpstr:='http://'+frouterip+':'+inttostr(frouterport)+frouterurl;<br> furlbase:='';<br> j:=pos('/',tmpstr);<br> while j>0 do<br> begin<br> furlbase:=furlbase+copy(tmpstr,1,j);<br> delete(tmpstr,1,j);<br> j:=pos('/',tmpstr);<br> end;<br> delete(furlbase,length(furlbase),1);<br>//<br>// 若数据无效...<br> if (trim(fRouterIp)='') or (fRouterPort<=0) then<br> begin<br> //<br> // 激发一个任务失败事件...<br> if ftasktype=1 then<br> failevent; {激发失败事件}<br> end<br>//<br>// 若成功...<br> else<br> begin<br> //<br> // 激发一个任务成功事件...<br> if ftasktype=1 then<br> successevent; {激发成功事件}<br> end;<br>end;<br><br>//<br>// 超时时间到的事件...<br>procedure TAutoNAT.TaskTimerTimer(Sender: TObject);<br>begin<br> failevent;<br> ftasktype:=-1; {撤消任务号}<br>end;<br><br>//<br>// 判定Socket的应答数据是否全部得到的函数...<br>function TAutoNAT.ResponseFinished(ResponseData: string): boolean;<br>var<br> head: string;<br> contentlength,j,headlength: integer;<br>begin<br> result:=false;<br>//<br>// 得到头信息...<br> j:=pos(#13#10#13#10,responsedata);<br> if j<=0 then<br> exit;<br> head:=copy(responsedata,1,j-1);<br> headlength:=j+3;<br>//<br>// 得到内容长度...<br> j:=pos('CONTENT-LENGTH:',uppercase(head));<br> if j<=0 then<br> begin<br> result:=true;<br> exit;<br> end;<br> delete(head,1,j+14);<br> j:=pos(#13#10,head);<br> try<br> contentlength:=strtoint(copy(head,1,j-1));<br> except<br> contentlength:=9999999;<br> end;<br>//<br>// 判定是否结束...<br> if (length(responsedata)-headlength)>=contentlength then<br> result:=true;<br>end;<br><br>//<br>// 提交查询请求...<br>procedure TAutoNAT.ClientSocketWrite(Sender: TObject; Socket: TCustomWinSocket);<br>begin<br>//<br>// 若已经发送请求,不再发送...<br> if requested then<br> exit;<br>//<br>// 发送前,先停止定时器...<br> tasktimer.enabled:=false;<br>//<br>// 发出请求...<br> response:=''; {还没有应答数据}<br> socket.SendBuf(request[1],length(request));<br> requested:=true; {已发送}<br>end;<br><br>//<br>// 得到Socket应答数据时(取控制页信息、增加NAT、删除NAT,以及取外网IP时的应答)...<br>procedure TAutoNAT.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);<br>var<br> tmpstr: string;<br> j: integer;<br>begin<br>//<br>// 接收数据,放到Response变量中...<br> j:=socket.ReceiveLength;<br> setlength(tmpstr,j);<br> socket.ReceiveBuf(tmpstr[1],j);<br> response:=response+tmpstr;<br>//<br>// 若应答数据未全部得到,等待下个读事件...<br> if not responsefinished(response) then<br> exit;<br>//<br>// 若已经全部得到,进行结果解析...<br> case ftasktype of<br> //<br> // 取控制页地址时...<br> 2: begin<br> tmpstr:=response;<br> //<br> // 得到基地址...<br> j:=pos(uppercase('<URLBASE>'),uppercase(tmpstr));<br> if j>0 then<br> begin<br> delete(tmpstr,1,j+length('<URLBASE>')-1);<br> j:=pos(uppercase('</URLBASE>'),uppercase(tmpstr));<br> if j>1 then<br> furlbase:=copy(tmpstr,1,j-1);<br> end;<br> //<br> // 查找设备urn:schemas-upnp-org:device:InternetGatewayDevice:1的描述段...<br> j:=pos(uppercase('<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>'),uppercase(tmpstr));<br> if j<=0 then<br> begin<br> failevent;<br> socket.Close; {关闭套接字}<br> exit;<br> end;<br> delete(tmpstr,1,j+length('<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>')-1);<br> //<br> // 再查找urn:schemas-upnp-org:device:WANDevice:1的描述段...<br> j:=pos(uppercase('<deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType>'),uppercase(tmpstr));<br> if j<=0 then<br> begin<br> failevent;<br> socket.Close; {关闭套接字}<br> exit;<br> end;<br> delete(tmpstr,1,j+length('<deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType>')-1);<br> //<br> // 再查找urn:schemas-upnp-org:device:WANConnectionDevice:1的描述段...<br> j:=pos(uppercase('<deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType>'),uppercase(tmpstr));<br> if j<=0 then<br> begin<br> failevent;<br> socket.Close; {关闭套接字}<br> exit;<br> end;<br> delete(tmpstr,1,j+length('<deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType>')-1);<br> //<br> // 最后找到服务urn:schemas-upnp-org:service:WANIPConnection:1的描述段...<br> j:=pos(uppercase('<serviceType>urn:schemas-upnp-org:service:WANIPConnection:1</serviceType>'),uppercase(tmpstr));<br> if j<=0 then<br> begin<br> failevent;<br> socket.Close; {关闭套接字}<br> exit;<br> end;<br> delete(tmpstr,1,j+length('<serviceType>urn:schemas-upnp-org:service:WANIPConnection:1</serviceType>')-1);<br> //<br> // 得到ControlURL...<br> j:=pos(uppercase('<controlURL>'),uppercase(tmpstr));<br> if j<=0 then<br> begin<br> failevent;<br> socket.Close; {关闭套接字}<br> exit;<br> end;<br> delete(tmpstr,1,j+length('<controlURL>')-1);<br> j:=pos(uppercase('</controlURL>'),uppercase(tmpstr));<br> if j<=0 then<br> begin<br> failevent;<br> socket.Close; {关闭套接字}<br> exit;<br> end;<br> fcontrolurl:=copy(tmpstr,1,j-1);<br> //<br> if (copy(urlbase,length(urlbase),1)='/') and (copy(fcontrolurl,1,1)='/') then<br> delete(fcontrolurl,1,1);<br> if (copy(urlbase,length(urlbase),1)<>'/') and (copy(fcontrolurl,1,1)<>'/') then<br> fcontrolurl:='/'+fcontrolurl;<br> fcontrolurl:=urlbase+fcontrolurl;<br> //<br> // 激发成功事件...<br> successevent;<br> end;<br> //<br> // 增加NAT项时...<br> 3: begin<br> tmpstr:=response;<br> j:=pos(#13#10,tmpstr);<br> tmpstr:=uppercase(copy(tmpstr,1,j-1));<br> //<br> // 假如成功...<br> if pos('200 OK',tmpstr)>0 then<br> successevent<br> //<br> // 假如失败...<br> else<br> failevent;<br> end;<br> //<br> // 取外网地址时...<br> 4: begin<br> tmpstr:=response;<br> j:=pos(#13#10,tmpstr);<br> tmpstr:=uppercase(copy(tmpstr,1,j-1));<br> //<br> // 假如成功...<br> if pos('200 OK',tmpstr)>0 then<br> begin<br> //<br> // 得到外网IP...<br> j:=pos(uppercase('<NewExternalIPAddress>'),uppercase(response));<br> if j<=0 then<br> fexternalip:='0.0.0.0'<br> else<br> begin<br> fexternalip:=response;<br> delete(fexternalip,1,j+length('<NewExternalIPAddress>')-1);<br> j:=pos(uppercase('</NewExternalIPAddress>'),uppercase(fexternalip));<br> if j<=0 then<br> fexternalip:='0.0.0.0'<br> else<br> fexternalip:=copy(fexternalip,1,j-1);<br> end;<br> //<br> // 激发成功事件...<br> successevent;<br> end<br> //<br> // 假如失败...<br> else<br> failevent;<br> end;<br> //<br> // 删除NAT项时...<br> 5: begin<br> tmpstr:=response;<br> j:=pos(#13#10,tmpstr);<br> tmpstr:=uppercase(copy(tmpstr,1,j-1));<br> //<br> // 假如成功...<br> if pos('200 OK',tmpstr)>0 then<br> successevent<br> //<br> // 假如失败...<br> else<br> failevent;<br> end;<br> end;<br>//<br>// 断开...<br> socket.Close; {关闭套接字}<br>end;<br><br>//<br>// 屏蔽可能出现的错误...<br>procedure TAutoNAT.ClientSocketError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);<br>begin<br> if taskexecuting then<br> failevent;<br> errorcode:=0;<br>end;<br><br>//<br>// 断开时...<br>procedure TAutoNAT.ClientSocketDisconnect(Sender: TObject; Socket: TCustomWinSocket);<br>begin<br> if taskexecuting then<br> failevent;<br>end;<br><br>//<br>// 搜索路由器设备(任务1)...<br>function TAutoNAT.SearchRouter(): boolean;<br>var<br> tmpstr: string;<br> buffer: array [0..4096] of char;<br> j: integer;<br>begin<br>//<br>// 假如定时器处于开启状态,异常返回...<br> if tasktimer.enabled then<br> begin<br> result:=false;<br> exit;<br> end;<br>//<br>// 生成路由器搜索请求...<br> tmpstr:='M-SEARCH * HTTP/1.1'#13#10<br> +'HOST: 239.255.255.250:1900'#13#10<br> +'MAN: "ssdp:discover"'#13#10<br> +'MX: 3'#13#10<br> +'ST: upnp:rootdevice'#13#10#13#10;<br> j:=length(tmpstr);<br> strplcopy(buffer,tmpstr,j);<br>//<br>// 设置各标志...<br> ftasktype:=1; {设备搜索任务}<br> taskexecuting:=true; {任务在执行}<br> taskfinished:=false; {任务未完成}<br> tasksuccess:=false; {任务未成功}<br> requested:=false; {未提交请求}<br>//<br>// 启动延时定时器...<br> tasktimer.interval:=ftimeout; {超时值}<br> tasktimer.enabled:=true;<br>//<br>// 发送请求,搜索路由器...<br> udp.SendBuffer(buffer,j); {发送设备搜索数据包}<br>//<br>// 返回成功...<br> result:=true;<br>end;<br><br>//<br>// 得到路由器控制页{任务2}...<br>function TAutoNAT.GetControlURL(): boolean;<br>begin<br>//<br>// 假如有任务在执行,返回失败...<br> if tasktimer.enabled then<br> begin<br> result:=false;<br> exit;<br> end;<br>//<br>// 生成请求串...<br> request:='GET '+frouterurl+' HTTP/1.1'#13#10<br> +'Host: '+frouterip+':'+inttostr(frouterport)+#13#10#13#10;<br>//<br>// 设置各标志...<br> ftasktype:=2; {设备搜索任务}<br> taskexecuting:=true; {任务在执行}<br> taskfinished:=false; {任务未完成}<br> tasksuccess:=false; {任务未成功}<br> requested:=false; {未提交请求}<br>//<br>// 启动延时定时器...<br> tasktimer.interval:=ftimeout; {超时值}<br> tasktimer.enabled:=true;<br>//<br>// 连接路由器...<br> sock.host:=frouterip; {路由器IP地址}<br> sock.port:=frouterport; {路由器端口号}<br> sock.active:=true; {连接路由器}<br>//<br>// 返回成功...<br> result:=true;<br>end;<br><br>//<br>// 增加端口映射项(任务3)...<br>function TAutoNAT.AddNatMapping(NatPortName: string; ExternalPort: integer; LocalIp: string; LocalPort: integer; Protocol: string): boolean;<br>var<br> url,body: string;<br> j: integer;<br>begin<br>//<br>// 假如有任务在执行,返回失败...<br> if tasktimer.enabled then<br> begin<br> result:=false;<br> exit;<br> end;<br>//<br>// 生成请求串...<br> body:='<?xml version="1.0"?>'#13#10<br> +'<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"'#13#10<br> +'s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'#13#10<br> +'<s:Body>'#13#10<br> +'<u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">'#13#10<br> +'<NewRemoteHost></NewRemoteHost>'#13#10<br> +'<NewExternalPort>'+inttostr(externalport)+'</NewExternalPort>'#13#10<br> +'<NewProtocol>'+protocol+'</NewProtocol>'#13#10<br> +'<NewInternalPort>'+inttostr(localport)+'</NewInternalPort>'#13#10<br> +'<NewInternalClient>'+localip+'</NewInternalClient>'#13#10<br> +'<NewEnabled>1</NewEnabled>'#13#10<br> +'<NewPortMappingDescription>'+natportname+'</NewPortMappingDescription>'#13#10<br> +'<NewLeaseDuration>0</NewLeaseDuration>'#13#10<br> +'</u:AddPortMapping>'#13#10<br> +'</s:Body>'#13#10<br> +'</s:Envelope>'#13#10;<br> //<br> url:=fcontrolurl;<br> delete(url,1,7);<br> j:=pos('/',url);<br> delete(url,1,j-1);<br> //<br> request:='POST '+url+' HTTP/1.1'#13#10<br> +'Host: '+frouterip+':'+inttostr(routerport)+#13#10<br> +'SoapAction: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"'#13#10<br> +'Content-Type: text/xml; charset="utf-8"'#13#10<br> +'Content-Length: '+inttostr(length(body))+#13#10#13#10+body;<br>//<br>// 设置各标志...<br> ftasktype:=3; {设备搜索任务}<br> taskexecuting:=true; {任务在执行}<br> taskfinished:=false; {任务未完成}<br> tasksuccess:=false; {任务未成功}<br> requested:=false; {未提交请求}<br>//<br>// 启动延时定时器...<br> tasktimer.interval:=ftimeout; {超时值}<br> tasktimer.enabled:=true;<br>//<br>// 连接路由器...<br> sock.host:=frouterip; {路由器IP}<br> sock.port:=frouterport; {端口}<br> sock.active:=true;<br>//<br>// 返回成功...<br> result:=true;<br>end;<br><br>//<br>// 取外网IP地址(任务4)...<br>function TAutoNAT.GetExternalIp(): boolean;<br>var<br> url,body: string;<br> j: integer;<br>begin<br>//<br>// 假如有任务在执行,返回失败...<br> if tasktimer.enabled then<br> begin<br> result:=false;<br> exit;<br> end;<br>//<br>// 生成请求串...<br> body:='<?xml version="1.0"?>'#13#10<br> +'<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'#13#10<br> +'<s:Body>'#13#10<br> +'<u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">'#13#10<br> +'</u:GetExternalIPAddress>'#13#10<br> +'</s:Body>'#13#10<br> +'</s:Envelope>'#13#10;<br> //<br> url:=fcontrolurl;<br> delete(url,1,7);<br> j:=pos('/',url);<br> delete(url,1,j-1);<br> //<br> request:='POST '+url+' HTTP/1.0'#13#10<br> +'Host: '+frouterip+':'+inttostr(frouterport)+#13#10<br> +'SoapAction: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"'#13#10<br> +'Content-Type: text/xml; charset="utf-8"'#13#10<br> +'Content-Length: '+inttostr(length(body))+#13#10#13#10+body;<br>//<br>// 设置各标志...<br> ftasktype:=4; {设备搜索任务}<br> taskexecuting:=true; {任务在执行}<br> taskfinished:=false; {任务未完成}<br> tasksuccess:=false; {任务未成功}<br> requested:=false; {未提交请求}<br>//<br>// 启动延时定时器...<br> tasktimer.interval:=ftimeout; {超时值}<br> tasktimer.enabled:=true;<br>//<br>// 连接路由器...<br> sock.host:=frouterip;<br> sock.port:=frouterport;<br> sock.active:=true;<br>//<br>// 返回成功...<br> result:=true;<br>end;<br><br>//<br>// 删除端口映射项(任务5)...<br>function TAutoNAT.DeleteNatMapping(ExternalPort: integer; Protocol: string): boolean;<br>var<br> url,body: string;<br> j: integer;<br>begin<br>//<br>// 假如有任务在执行,返回失败...<br> if tasktimer.enabled then<br> begin<br> result:=false;<br> exit;<br> end;<br>//<br>// 生成请求串...<br> body:='<?xml version="1.0"?>'#13#10<br> +'<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'#13#10<br> +'<s:Body>'#13#10<br> +'<u
eletePortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">'#13#10<br> +'<NewRemoteHost></NewRemoteHost>'#13#10<br> +'<NewExternalPort>'+inttostr(externalport)+'</NewExternalPort>'#13#10<br> +'<NewProtocol>'+protocol+'</NewProtocol>'#13#10<br> +'</u
eletePortMapping>'#13#10<br> +'</s:Body>'#13#10<br> +'</s:Envelope>'#13#10;<br> //<br> url:=fcontrolurl;<br> delete(url,1,7);<br> j:=pos('/',url);<br> delete(url,1,j-1);<br> //<br> request:='POST '+url+' HTTP/1.0'#13#10<br> +'Host: '+routerip+':'+inttostr(routerport)+#13#10<br> +'SoapAction: "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"'#13#10<br> +'Content-Type: text/xml; charset="utf-8"'#13#10<br> +'Content-Length: '+inttostr(length(body))+#13#10#13#10+body;<br>//<br>// 设置各标志...<br> ftasktype:=5; {设备搜索任务}<br> taskexecuting:=true; {任务在执行}<br> taskfinished:=false; {任务未完成}<br> tasksuccess:=false; {任务未成功}<br> requested:=false; {未提交请求}<br>//<br>// 启动延时定时器...<br> tasktimer.interval:=ftimeout; {超时值}<br> tasktimer.enabled:=true;<br>//<br>// 连接路由器...<br> sock.host:=frouterip;<br> sock.port:=frouterport;<br> sock.active:=true;<br>//<br>// 返回成功...<br> result:=true;<br>end;<br><br>end.