//客户端的代码
procedure UDPSocks(Sclient:Tsocket;tarsocksrv:TSockAddr;var buf);//buf是要发送的数据
var
    saproxy:TSockAddr;
    pSocksAddr:Pchar;
    Re:integer;
    ErrCode:Integer;
    AuthSucc:boolean;
    ConSucc:boolean;
    serverip,serverport:String;
    namelen:integer;
    destport:integer;
    destip: String;
begin    serverip:='192.168.0.100; //代理服务器ip
    serverport:='1080';       //代理服务器port    namelen:=sizeof(tarsocksrv);
    getpeername(Sclient,tarsocksrv,namelen);
    destip:=inet_ntoa(tarsocksrv.sin_addr);  //获取目标IP
    destport:=ntohs(tarsocksrv.sin_port);    //获取目标port
    
    sclient:=socket(AF_INET,SOCK_DGRAM,0);//不知道这里设SOCK_DGRAM对不对?
    if(sclient=INVALID_SOCKET) then
    begin
      Exit;
    end;
    ZeroMemory(@saproxy,sizeof(saproxy));
    saproxy.sin_family := AF_INET;
    GetMem(pSocksAddr,Length(serverip)+1);
    ZeroMemory(pSocksAddr,Length(serverip)+1);
    StrPCopy(pSocksAddr,serverip);
    saproxy.sin_addr.S_addr :=inet_addr(pSocksAddr);
    FreeMem(pSocksAddr);
    saproxy.sin_port := htons(strtoint(serverport));
    Re:=connect(sclient,saproxy,sizeof(saproxy));
    if Re = SOCKET_ERROR then
        begin
            ErrCode:=WSAGetLastError();
            Exit;
        end;
    AuthSucc:=publicAuth(sclient);//版本和密码账号验证,这个函数就不贴了。。
   if not AuthSucc then
   begin
      CloseSocket(sclient);
      Exit;
   end;
    ZeroMemory(@tarsocksrv,Sizeof(tarsocksrv));
    Getmem(psocksaddr,length(destip)+1);
    zeromemory(psocksaddr,length(destip)+1);
    strpcopy(psocksaddr,destip);
    tarsocksrv.sin_addr.s_addr := inet_addr(pSocksAddr);
    tarsocksrv.sin_port := htons(destport);
    tarsocksrv.sin_family := AF_INET;
//*******************************************************************
    consucc:=UDPconnect(Sclient,tarsocksrv,buf);//发送udp数据。
//*******************************************************************
    Re:= closesocket(Sclient);
end;
function UDPconnect(skt: TSocket; target: TSockAddr;var buf):Boolean;//发送udp数据。
var
    UDPbuf:array[0..2048]of byte;
    re:integer;begin
//发送udp数据的时候要在前头加10字节的格式数据。
     UDPbuf[0]:=$00;
     UDPbuf[1]:=$00;
     UDPbuf[2]:=$00;
     UDPbuf[3]:=$01;
     copymemory(@UDPbuf[4],@target.sin_addr,4);
     copymemory(@UDPbuf[8],@target.sin_port,2);
     copymemory(@UDPbuf[10],@buf,sizeof(buf));
     re:=send(skt,UDPbuf,sizeof(UDPbuf),0);
     zeromemory(@UDPbuf, 2049);
     re :=recv(skt,UDPbuf,1024,0);
     if re=-1 then
     begin
      result:=false;
      exit;
     end;
     if UDPbuf[1]<>REP_SUCCESS then
     begin
      result:=false;
      exit;
     end;
     result:=true;
end;
//这代码不能发送UDP数据,希望帮修改下。

解决方案 »

  1.   

    供参考:
    unit Main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Mask, ExtCtrls, Buttons, IdUDPServer, IdBaseComponent,
      IdComponent, IdUDPBase, IdUDPClient,IdSocketHandle;type
      TFrmMain = class(TForm)
        GroupBox1: TGroupBox;
        GroupBox2: TGroupBox;
        GroupBox3: TGroupBox;
        Label1: TLabel;
        Label2: TLabel;
        Edit1: TEdit;
        Label3: TLabel;
        Edit2: TEdit;
        MReceivd: TMemo;
        BtnSet: TBitBtn;
        RadioGroup1: TRadioGroup;
        RadioGroup2: TRadioGroup;
        BtnSend: TBitBtn;
        EdtCommand: TEdit;
        BtnClose: TBitBtn;
        IdUDPClient: TIdUDPClient;
        IdUDPServer: TIdUDPServer;
        CheckBox1: TCheckBox;
        Edit3: TEdit;
        CheckBox2: TCheckBox;
        procedure BtnCloseClick(Sender: TObject);
        procedure BtnSendClick(Sender: TObject);
        procedure BtnSetClick(Sender: TObject);
        procedure Edit1KeyPress(Sender: TObject; var Key: Char);
        procedure Edit2KeyPress(Sender: TObject; var Key: Char);
        procedure IdUDPServerUDPRead(Sender: TObject; AData: TStream;
          ABinding: TIdSocketHandle);
        procedure FormShow(Sender: TObject);
        procedure RadioGroup1Click(Sender: TObject);
        procedure Edit3KeyPress(Sender: TObject; var Key: Char);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      FrmMain: TFrmMain;
    const
      RECIEVETIMEOUT = 5000; // 毫秒implementationuses PubFuction;{$R *.dfm}procedure TFrmMain.BtnCloseClick(Sender: TObject);
    begin
      IdUDPClient.Active := False;
      IdUDPServer.Active := False;
      Close;
    end;procedure TFrmMain.BtnSendClick(Sender: TObject);
    var
      SendData: string;
    begin
      if RadioGroup2.ItemIndex = 0 then
        SendData := Trim(EdtCommand.Text)
      else
        SendData := HexToString(Cutblank_wanjun(Trim(EdtCommand.Text)));
      if CheckBox2.Checked then
         SendData := SendData + hextostring(inttohex(crc16(SendData,length(SendData)),4));
      IdUDPClient.Send(SendData);
    end;procedure TFrmMain.BtnSetClick(Sender: TObject);
    begin
      if (Edit3.Text = '') or (Edit1.Text = '')
        or (Edit2.Text = '') then
      begin
        MessageBox(HANDLE,'请将参数添加完整!','信息提示',MB_ICONWARNING + MB_OK);
        exit;
      end;
      IdUDPClient.Host := Trim(Edit3.Text);
      IdUDPClient.Port := StrToInt(Trim(Edit1.Text));
      IdUDPClient.ReceiveTimeout := RECIEVETIMEOUT;
      IdUDPServer.DefaultPort := StrToInt(Trim(Edit2.Text));
      IdUDPServer.Active := True;
      BtnSend.Enabled :=True;
    end;procedure TFrmMain.Edit1KeyPress(Sender: TObject; var Key: Char);
    begin
      if not(key in['0'..'9',#8]) then
        key:=#0;
    end;procedure TFrmMain.Edit2KeyPress(Sender: TObject; var Key: Char);
    begin
      if not(key in['0'..'9',#8]) then
        key:=#0;
    end;procedure TFrmMain.IdUDPServerUDPRead(Sender: TObject; AData: TStream;
      ABinding: TIdSocketHandle);
    var
      ReturnData: array[0..1024] of char;
    begin
      AData.Read(ReturnData,AData.Size);
      ReturnData[AData.Size] := #0;
      if self.CheckBox1.Checked then
        MReceivd.Lines.Clear;
      if RadioGroup1.ItemIndex = 0 then
        MReceivd.Lines.Add(ReturnData)
      else
        MReceivd.Lines.Add(Showstr(ReturnData,AData.Size));
    end;procedure TFrmMain.FormShow(Sender: TObject);
    begin
      Edit3.SetFocus;
    end;procedure TFrmMain.RadioGroup1Click(Sender: TObject);
    var
      sText: string;
    begin
      if MReceivd.Text <> '' then
      begin
        if RadioGroup1.ItemIndex = 0 then
        begin
          sText := hexTostring(Cutblank_wanjun(MReceivd.Text));
          MReceivd.Text := sText;
        end
        else
        begin
          MReceivd.Text := ShowStr(Pchar(MReceivd.Text),length(MReceivd.Text));
       end;
      end;
    end;procedure TFrmMain.Edit3KeyPress(Sender: TObject; var Key: Char);
    begin
      if not(key in['0'..'9',#8,#$2e]) then  
        key:=#0;
    end;end.
      

  2.   

    谢谢2楼供参考,Socks5代理我不用控件,想自己编写。