300分求解:应用程序已经做完,Sock和UDP通过代理通信问题请朋友们帮忙解决,谢谢,分数不够可以再加。(300分)

  • 主题发起人 主题发起人 goeasy
  • 开始时间 开始时间
G

goeasy

Unregistered / Unconfirmed
GUEST, unregistred user!
我做完了一个关于网络上的应用程序。程序的客户端和服务器端都在局域网或者外网,应用程序可以。但是,客户端通过代理上网,服务器再返回信息时,无法认识客户端,只认识代理服务器,所以不能够通信。因为是多个客户端,一个端口,在映射的时候只能够是一台机器,所以也不行。代理通信的原理我全看了,包括以前的论坛,但是没有一个完美的解决方案。我想请教解决过这个问题的朋友,给我一个解决的方案,希望有代码,我将不胜感激!!!请邮寄:xuqiang@dsideal.com
 
代理通信需要完美解决方案吗,这只是一套技术标准,照标准做就可以了
 
上面的朋友误会了,我不是说自己做代理,我是说如何让我们的程序在客户用代理的情况下应用呢?当然,我的程序可以改动一些。做过的朋友可以给些经验,理论上我明白了,但是却不知道如何对程序下手。。。。。。。
 
看一些这方面的资料吧。帮你提前吧
 
你什么需要加入代理功能呀。
怎样解决TSocketConnection的Socks5代理的问题。
http://www.delphibbs.com/keylife/iblog_show.asp?xid=4143
 
这里只是改动的一部分,谁有没有具体的呢?程序支持Sockes5的原理谁可以给解释解释?如果客户的代理软件是WinRoute,我们是不是要改动他的代理使代理也支持Sockes5呢?如何改。请朋友们帮忙,探讨。
 
Socket通过代理的代码我已经做完了。但是 UDP连接代理的过程中我遇到了一个问题。 在Socket和代理通讯请求连接的过程中,我已经实现了第七步:
7.需要申请方发送
00 00 00 01 +目的地址IP(4字节)+目的端口 +所要发送的信息
8。当有数据报返回时
向需要代理方发出00 00 00 01 +来源地址IP(4字节)+来源端口 +接受的信息

当第七步完成后,有UDP控件的服务器端收不到信息(说明和远程UDP没有连接)。但是,Client端的ClientSocket却收到了信息,是不是就是第八步所说的“当有数据报返回时”,如果是,那么下一句话是什么意思呢?我该如何做呢?“来源地址IP”的来源是什么呢?
谁能够给出具体代码或者说明,解决后立即结帖。谢谢大家。。。
 
需要说明的是,UDP的Socks5代理模式,
刚开始用来建立连接的TCP连接必须保持,直到UDP会话完成
如果此TCP连接被断开,则代理的UDP端口也会失效

目的地址和端口,表示你的数据要通过代理服务器转发到哪里
来源地址和端口,表示你接收的数据是从哪里来的
数据报的发送和接收都是在UDP上完成的,
你的clientSocket仅仅是用来保持这个UDP代理连接

我不知道你的建立连接的过程是什么样的,都是哪8步

是这样吗?
1.请求验证模式
2.进行验证,
3.UDP ASSOCIATE一个端口
每个请求都要求返回成功,
而且最后一步返回的端口不一定能够成功,必须和代理服务器进行协商
在UDP连接请求的回应中,BND.PORT和BND.ADDR域指明了客户端需要被发送UDP请求消息的端口号/地址。

上面的步骤都成功之后,就可以用UDP发送信息了
发送和接收的每个数据报都被加上了一个头部,
自己通过解析可以去掉,或者发送数据前将其加上

 
谢谢lich朋友,我连接的过程是这样的(无身份验证):
1、Socket连接代理服务器
2、成功后,向代理发送050100
3、Socket接收到返回信息:0500(说明可以代理)
4、Socket向代理发送05 03 00 01 00 00 00 00+本地UDP端口(我用的是indy里Client的UDP)
5、Socket接收到返回信息:05000001+代理服务器ip+代理给分配的动态端口
6、(在这里有人说需要断开Socket?)(断开:完成7后没有反应;不断开:完成7后Socket还会接收到返回信息)
7、用ClientUDP向代理服务器发送:00000001+远程UDP服务器地址+远程UDP服务器端口
在完成7步后,我的UDP服务器端没有接收到任何数据。(在这里,UDP的Host我指定为代理IP,端口用9001或者5步接收的动态端口我都试了);
论坛里有人说第八步为:
8、当有数据报返回时
向需要代理方发出00 00 00 01 +来源地址IP(4字节)+来源端口 +接受的信息

但是我在这里不理解了,如何判断有数据报返回(indy的ClientUDP不能够接收数据啊),如果是Sock不短开情况下接收的数据算返回的话,那么"向需要代理方发出"是说谁呢?代理服务器还是远程UDP服务器?来源地址IP和来源端口我又如何设置呢?
请求lich及各位朋友给我指点迷津,谢谢各位了!!!!如果有相关UDP代码借鉴就更谢谢了:xuqiang@dsideal.com



 
我写了一个测试程序,改天我会贴出来
 
谢谢lich朋友的热心,我可期待着呢,我这里先谢过lich老师了。

现在网络上所有的资料都是对NMUDP来做测试的,但是对indy里的udp却没有资料,希望linch老师能够用indy里的UDP做测试。
NMUDP和indy的UDP区别是:NMUDP可以接收数据,而indy中的UDP Client端不能够接收信息,Server端可以接收信息,这样,通过代理我就不知道如何做了。
希望知道具体UDP使用代理的老师们给予帮助,万分感激啊!!!!
 
lich老师,你有QQ,MSN或者邮件告诉我吗?我可以通过这些方式和您学习,我的Mail:xuqiang@dsideal.com
 
用SOCKET自己写!!我回去看看我的代码还能找到吗?
 
谢谢楼上的热心朋友。
自己写代理转发程序我到是考虑过,也能够实现。主要是应用程序如果给客户的时候,有的客户有代理,有的没有。再说,如果自己写代理,那么还需要客户在他原有代理的机器上再安装一套咱们的代理软件,这样人家。。。。
所以,我想,自己的程序如果能够通过已有的代理走出去是最好的了,并且这个思路一定可以实现。Socket我已经实现了。现在UDP的有以上问题。并且,我在需要走代理的客户端运行"SockesCap"这个软件,我的程序就可以运行了。
我想,国外可以做出这样的软件,我在朋友们的帮助下也一定能够做出来。我也希望得到这方面高手朋友们的支持。
 
客户有代理你就用SOCKET写一个连接不就行了。
 
是的,Socket的我已经写完了,实现了。但是现在UDP在连接的过程中出现了上面的问题,希望做过UDP连接Sockes5代理的朋友帮忙解决。
 
顺便说一下,通过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;
 
非常感谢lich老师,结帖。
 
后退
顶部