顺便说一下,通过Socks5只能实现UDP客户端功能,
也就是说,第一个数据包,只能由客户端发向服务器端
然后就可以互相发送了
我已经修改了这个程序,贴出部分代码:
function TForm1.UdpSend(Host: String; Port: Integer;
Data: String): Integer;
var
Header: String;
t: Integer;
s: String;
Buff: array[1..5000] of Char;
begin
SetLength(Header, 500);
Header[1] := #0;
Header[2] := #0;
Header[3] := #0;
Header[4] := #3; //AType: Host Name
Header[5] := Chr(Length(Host));
Move(PChar(Host)^, Header[6], Length(Host));
t := 6 + Length(Host);
Header[t] := #0;
t := t + 1;
Header[t] := #13; //Daytime service
SetLength(Header, t);
s := Header + Data;
if ComType = 1 then //Use FastNet.NMUDP
begin
Move(PChar(s)^, Buff, Length(s)); //转化为字符数组
NMUDP1.SendBuffer(Buff, Length(s)); //进行发送
end
else if ComType = 2 then //Use IdUDPServer
begin
IdUDPServer1.Send(SAddr, SPort, s);
end;
Result := Length(Data);
end;
function TForm1.UdpDecode(Buff: String; var Host: String;
var Port: Integer): String;
var
t: Integer;
Len: Integer;
begin
Len := Length(Buff);
if Len >= 5 then
begin
case Buff[4] of
#1: //IPv4
begin
if Len >= 10 then
begin
Host := Format('%d.%d.%d.%d',
[Byte(Buff[5]), Byte(Buff[6]),
Byte(Buff[7]), Byte(Buff[8])]);
Port := Byte(Buff[9]) * 256 + Byte(Buff[10]);
t := 11;
end
else t := 0;
end;
#3: //Host
begin
t := Byte(Buff[5]);
if (t > 0) and (Len >= t + 4 + 1 + 2) then
begin
SetLength(Host, t);
Move(Buff[6], Host[1], t);
t := t + 5 + 1;
Port := Byte(Buff[t]) * 256 + Byte(Buff[t + 1]);
t := t + 2;
end
else t := 0;
end;
else t := 0;
end;
if t > 0 then
begin
Result := Copy(Buff, t, Length(Buff));
end;
end
else
begin
Host := '';
Port := 0;
Result := '';
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
UdpSend(Trim(Edit3.Text), 13, 'test');
end;
procedure TForm1.Button3Click(Sender: TObject);
var
s: String;
Buff: array[1..500] of Char;
begin
s := 'test';
if RadioGroup1.ItemIndex <= 0 then
begin
NMUDP1.LocalPort := 5028;
NMUDP1.RemoteHost := Edit3.Text;
NMUDP1.RemotePort := 13;
Move(PChar(s)^, Buff, Length(s));
NMUDP1.SendBuffer(Buff, Length(s));
end
else
begin
IdUDPServer1.Active := False;
IdUDPServer1.DefaultPort := 5033;
IdUDPServer1.Send(Edit3.Text, 13, s);
end;
end;
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
s: String;
Len: Integer;
d: String;
hs: String;
pt: Integer;
begin
if AData.Size > 0 then
begin
Len := AData.Size;
SetLength(s, Len + 500);
Len := AData.Read(PChar(s)^, Length(s));
SetLength(s, Len);
{** for debug only}
//Memo1.Lines.Text := s;
//Caption := Format('%d bytes received', [Len]);
if state = 10 then //仅仅在代理访问模式时进行这样的处理
begin
d := UdpDecode(s, hs, pt);
if d <> '' then
begin
Memo1.Lines.Add('USE IdUDPServer---');
Memo1.Lines.Add('Recv from: ' + hs + ',Port: ' + IntToStr(pt));
Memo1.Lines.Add(IntToStr(Length(d)) + ' bytes received');
Memo1.Lines.Add('Data: ');
Memo1.Lines.Add(d);
end;
end
else //正常模式
begin
Memo1.Lines.Add('IdUDPServer none Socks5 proxy mode ---');
Memo1.Lines.Add('Recv from: ' + ABinding.PeerIP + ',Port: ' +
IntToStr(ABinding.PeerPort));
Memo1.Lines.Add(IntToStr(Length(d)) + ' bytes received');
Memo1.Lines.Add('Data: ');
Memo1.Lines.Add(s);
end;
end;
end;
procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer; FromIP: String; Port: Integer);
var
s: String;
Len: Integer;
d: String;
hs: String;
pt: Integer;
begin
Len := NumberBytes;
if Len > 0 then
begin
SetLength(s, Len);
NMUDP1.ReadBuffer(PChar(s)^, Len);
{** for debug only}
//Memo1.Lines.Text := s;
//Caption := Format('%d bytes received', [NumberBytes]);
if state = 10 then //仅仅在代理访问模式时进行这样的处理
begin
d := UdpDecode(s, hs, pt);
if d <> '' then
begin
Memo1.Lines.Add('USE FastNet.NMUDP---');
Memo1.Lines.Add('Recv from: ' + hs + ',Port: ' + IntToStr(pt));
Memo1.Lines.Add(IntToStr(Length(d)) + ' bytes received');
Memo1.Lines.Add('Data: ');
Memo1.Lines.Add(d);
end;
end
else //正常模式
begin
Memo1.Lines.Add('FastNet.NMUDP none Socks5 proxy mode ---');
Memo1.Lines.Add('Recv from: ' + FromIP + ',Port: ' + IntToStr(Port));
Memo1.Lines.Add(IntToStr(Length(d)) + ' bytes received');
Memo1.Lines.Add('Data: ');
Memo1.Lines.Add(s);
end;
end;
end;