to truexf :用TCP&UDP测试工具 做的服务器。我在测试工具中发的数据.这边程序就是收不到数据。 

解决方案 »

  1.   


    那你收什么?既然服务器没有数据发过来你的recv函数就会阻塞在哪里
      

  2.   

    先确定服务器端是否有返回数据,另外,不要在非主线程中操作vcl,例如118行就是错误的用法。
      

  3.   

    to truexf:啥都没收到。
    我把
     BeginThread(nil, 0, @Receive, PChar(skt),0, dThreadID);
    改成
     BeginThread(nil, 0, @Receive, nil,0, dThreadID);procedure Receive(Sock :TSocket);stdcall;改成
    procedure Receive();stdcall;可以接受到数据了,Why?
      

  4.   

    to pathletboy:嗯,好的,我记住了,我这个是练手程序,以前没用过API写SOCKET.这里调通了,再写到其他地方去的。
      

  5.   


    你线程函数的定义不对
    function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
      ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
      var ThreadId: LongWord): Integer;type
      TThreadFunc = function(Parameter: Pointer): Integer;这么定义
    function Receive(Sock :TSocket): Integer;
      

  6.   

    to truexf:
    to pathletboy:
      感谢你们2位,问题解决了,线程函数多加了个stdcall导致接收不到数据。 
      

  7.   

    delphi默认是pascal传参方式,前3个参数用寄存器,然后再用堆栈传参,stdcall是直接用堆栈传参,你线程函数定义为堆栈传参的话是无法接收到正确的参数的。
      

  8.   

    to pathletboy :学习了,我单步调的时候我也看到了Sock的值变了,我就没传参了,我后来临时一想,改成我上面的那样,也可以收到数据,就是没注意到stdcall,pathletboy正解。
      

  9.   

    Delphi API Socket 发送,接收十六进制数据 代码调通的贴下面了。unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, WinSock, StdCtrls;type
      TSocketComm=class(TObject)
      private  public
        constructor Create;
        destructor Destroy; override;
        function ConnectSvr: Integer;
        function SendFrame(Str_SendFrame: string): Integer;
      end;type
      TForm1 = class(TForm)
        btn1: TButton;
        btn2: TButton;
        edt_SendFrame: TEdit;
        mmo_Debug: TMemo;
        btn3: TButton;
        procedure btn1Click(Sender: TObject);
        procedure btn2Click(Sender: TObject);
        procedure btn3Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;
      skt:TSocket;
      LExit:Boolean;
      Svr_Addr,Clnt_Addr:TSockAddr;
      ClientSocket:TSocketComm;procedure Receive(Sock:TSocket);implementation{$R *.dfm}constructor TSocketComm.Create;
    var
        Wsa:TWSAData;
    begin
        inherited Create;
        if WSAStartup(MakeWord(2,2),Wsa)<>0 then
        begin
            ShowMessage('Init Socket failed');
            WSACleanup;
        end;
    end;destructor TSocketComm.Destroy;
    begin
        inherited destroy;
        WSACleanup;
        closesocket(skt);
    end;function TSocketComm.ConnectSvr():Integer;
    var
        dThreadID:DWORD;
        i_RtnCode:Integer;
    begin
        skt:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if skt=INVALID_SOCKET then
        begin
            ShowMessage('Create Socket failed');
            WSACleanup;
            Exit;
        end;
        Clnt_Addr.sin_family:=AF_INET;
        Clnt_Addr.sin_addr.S_addr:=inet_addr('127.0.0.1');
        Clnt_Addr.sin_port:=htons(StrToInt('2039'));
        bind(skt,Clnt_Addr,SizeOf(Clnt_Addr));    Svr_Addr.sin_family:=AF_INET;
        Svr_Addr.sin_addr.S_addr:=inet_addr('192.168.200.95');
        Svr_Addr.sin_port:=htons(StrToInt('2038'));
        i_RtnCode:=connect(skt,Svr_Addr,SizeOf(Svr_Addr));    if i_RtnCode<>0 then
        begin
            ShowMessage('Connect 192.168.200.95 failed');
            WSACleanup;
            Exit;
        end;
        LExit:=False;
        BeginThread(nil, 0, @Receive, PChar(skt),0, dThreadID);
    end;procedure Receive(Sock:TSocket);
    var
      Buffer: pChar;
      i,iRes: Integer;
      S,Str_RecByte:string;
      i_Buf:array[1..1024] of Byte;
    begin
        GetMem(Buffer, 1024);
        while not LExit do
        begin
            iRes := recv(Sock, Buffer^, 1024, 0);
            if iRes < 1 then
            begin
                Sleep(500);
                Continue;
            end;
            Move(Buffer^,i_Buf,iRes);
            for i:=1 to iRes do
            begin
                Str_RecByte:=IntToHex(i_Buf[i],2);
                S:=S+' '+Str_RecByte;
            end;
            if Copy(S,1,1)=' ' then
            begin
                Delete(S,1,1);
            end;
            Form1.mmo_Debug.Lines.Add(S);
            ZeroMemory(Buffer, 1024);
        end;
        FreeMem(Buffer);
       // CloseSocket(skt);
        ExitThread(0);
    end;function TSocketComm.SendFrame(Str_SendFrame:string):Integer;
    var
        i,i_FrameLen:Integer;
        i_Buf:array[1..1024] of Byte;
    begin
        Str_SendFrame:=StringReplace(Str_SendFrame,' ','',[rfReplaceAll]);
        i_FrameLen:=Length(Str_SendFrame) div 2;              //Convert string to byte string
        for i:=0 to i_FrameLen-1 do
        begin
            i_Buf[i+1]:=StrToInt('$'+Copy(Str_SendFrame,i*2+1,2));
        end;
        send(skt,i_Buf,i_FrameLen,0);
    end;procedure TForm1.btn1Click(Sender: TObject);
    begin
        ClientSocket:=TSocketComm.Create;
        ClientSocket.ConnectSvr;
    end;procedure TForm1.btn2Click(Sender: TObject);
    begin
    //    closesocket(skt);
        WSACleanup;
    end;procedure TForm1.btn3Click(Sender: TObject);
    begin
        ClientSocket.SendFrame(Trim(edt_SendFrame.Text));
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        btn2Click(nil);
    end;end.