[请不要不屑啊^_^]请问如何让自己的程序与别人的程序共享某个端口(TIdUDPServer)? (50分)

  • 主题发起人 主题发起人 cornermoss
  • 开始时间 开始时间
C

cornermoss

Unregistered / Unconfirmed
GUEST, unregistred user!
注意:不能更改“别人”的程序。
问题背景:
我的程序用到了67端口(Intel PXE服务),而Win2k的DHCP Server服务也用到了
67端口。如果先运行DHCP Server,再运行我的程序就不能正常运行,显示“Could
not bind socket.Address and port are already in use. ”如果先运行我的程
序,再运行DHCP Server,不会报错,可我的程序接收不到传来的请求了(这是否说
明DHCP Server的运行级别比我的程序高?)
但是用PXE SDK里的例子(C++),却能够一切正常,它是直接用的Socket;请问有
没有哪位大虾来看看怎么改TIdUDPServer,使它可以与别的程序共享端口呢?
 
端口好像不可以共亨的吧....
 
我也想知道
 
约定的情况为:
主程序Main,监听67端口,向68端口发送信息;
测试程序Test,监听68端口,向67端口发送信息;
DHCP Server为DHCP,监听67端口,向68端口发送信息(Win2K的帮助里:DHCP 服务器使用 UDP 端口 67 来监听和接收客户请求消息。DHCP 客户机一般保留 UDP 端口 68 用于接受来自 DHCP 服务器的消息回复。)
一.如果先运行DHCP,再运行Main或者Test,都会出错;
二.先运行Main和Test,然后再运行DHCP,此时Main能收到MAC地址为000000000000的包,应该是DHCP发出的;Test通过67端口发送信息,结果能收到68端口发过来的信息(经过分析,是DHCP发出的),而Main没有收到指定的信息。
三.通过第二步的测试后,停止DHCP,(Main和Test都没有关闭),Test向67发包,Main能收到正确信息。
这样,难道是因为DHCP服务比Main和Test级别要高吗?为什么Main和Test已使用了67和68端口,DHCP仍然能够正常运行呢?
 
下面是我改的Indy 8.0.25的IdStackWinsock.pas,注释部分是我加的,可运行时有错
function TIdStackWinsock.WSBind(ASocket: TIdStackSocketHandle;
const AFamily: Integer; const AIP: string;
const APort: Integer): Integer;
var
Addr: TSockAddrIn;
//modify by zxd 2004-05-20
// val : Boolean;
// ret : Integer;
//end modify
begin
Addr.sin_family := AFamily;
if length(AIP) = 0 then
begin
Addr.sin_addr.s_addr := INADDR_ANY;
end
else
begin
Addr.sin_addr := TInAddr(StringToTInAddr(AIP));
end;
Addr.sin_port := HToNS(APort);
//modify by zxd 2004-05-20
(* val := TRUE;
ASocket := Socket(AF_INET, SOCK_DGRAM, 0);
ret := SetSockOpt(ASocket,SOL_SOCKET,SO_REUSEADDR,PChar(@val),SizeOf(val));
if ((ret<>0) or (ASocket = INVALID_SOCKET)) then result :=-9
else
*) //end modify
result := Bind(ASocket, addr, SizeOf(Addr));
end;
 
下面的是一个测试程序,如果DHCP Server启动后再点击"active UDP"则会出错;如果先
"active UDP"后再启动DHCP Server,则测试程序会收到DHCP Server发出的包,可是此时
它自己不能给自己发包。这是为什么啊?测试环境 Delphi6.0 + Windows2000

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer,IdSocketHandle;

type
TForm1 = class(TForm)
MyUDP_67: TIdUDPServer;
MyUDP_68: TIdUDPServer;
Memo_67: TMemo;
Memo_68: TMemo;
btn_67Send: TButton;
btn_68Send: TButton;
et_toIP: TEdit;
btn_activeUDP: TButton;
procedure MyUDP_67UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
procedure MyUDP_68UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
procedure FormCreate(Sender: TObject);
procedure btn_67SendClick(Sender: TObject);
procedure btn_68SendClick(Sender: TObject);
procedure btn_activeUDPClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
Inc_67,Inc_68 : Integer;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.MyUDP_67UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
begin
Memo_67.Lines.Add('我是67,收到一条信息--------'+IntToStr(Inc_67));
Inc(Inc_67);
// btn_67SendClick(Sender);
end;

procedure TForm1.MyUDP_68UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
begin
Memo_68.Lines.Add('我是68,收到一条信息--------'+IntToStr(Inc_68));
Inc(Inc_68);
// btn_68SendClick(Sender);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Inc_67 := 1;
Inc_68 := 1;
end;

procedure TForm1.btn_67SendClick(Sender: TObject);
var strSend : String;
begin
strSend := '21543654645';
MyUDP_67.SendBuffer(et_toIP.Text,68,strSend,SizeOf(strSend));
end;

procedure TForm1.btn_68SendClick(Sender: TObject);
var strSend : String;
begin
strSend := '21543654645';
MyUDP_68.SendBuffer(et_toIP.Text,67,strSend,SizeOf(strSend));
end;

procedure TForm1.btn_activeUDPClick(Sender: TObject);
begin
if btn_activeUDP.Caption='Active UDP' then
begin
try
MyUDP_67.Active:=True;
MyUDP_68.Active:=True;
btn_activeUDP.Caption := 'stop UDP';
except MessageBox(0,PChar('启动失败!'),'',MB_OK);
end;
end
else
begin
MyUDP_67.Active:=False;
MyUDP_68.Active:=False;
btn_activeUDP.Caption := 'Active UDP';
Memo_67.Lines.Add('★★★★★★★★★★★');
Memo_68.Lines.Add('★★★★★★★★★★★');
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
MyUDP_67.Active:=False;
MyUDP_68.Active:=False;
end;

end.
 
后退
顶部