想要做个关于股票行情的实时发送和接收的Server,Client,哪位大侠来帮忙啊。55555555
   可以提供个简单的代码的最好。就是Server接收固定服务器的行情,如果有请求,再实时将行情发送给Client显示,就这基本功能就可以了!想使用UDP来发送。

解决方案 »

  1.   

    UDP是不可靠的,对于你的应用程序,建议不要使用
      

  2.   

    我以前测试的时候写过一个程序,在两台机器上运行可以相互发消息。发送和接收的消息都保存在一个listbox里,接收到的消息以*号开头,发送的消息以-号开头,发出的消息如果对方有回应,前面的-号变成+号。unit UdpMain;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls, blcksock;const
      WM_TERMINATE = WM_USER + 1;
      WM_UDPDOSEND = WM_USER + 2;
      
      WM_UDPRECVED = WM_USER + 51;type
      TUDPRecvThread = class(TThread)
      public
        procedure Execute; override;
      end;  TUDPSendThread = class(TThread)
      public
        procedure Execute; override;
      end;  TUDPForm = class(TForm)
        Label1: TLabel;
        ListMsg: TListBox;
        EdAddrTo: TEdit;
        Label2: TLabel;
        EdPortTo: TEdit;
        Label3: TLabel;
        Panel1: TPanel;
        Label4: TLabel;
        Label5: TLabel;
        EdAddrSocks: TEdit;
        Label6: TLabel;
        EdPortSocks: TEdit;
        Label7: TLabel;
        EdUserName: TEdit;
        Label8: TLabel;
        EdPassword: TEdit;
        BtnSend: TButton;
        Label9: TLabel;
        EdMsg: TEdit;
        Label10: TLabel;
        EdPortLocal: TEdit;
        BtnStart: TButton;
        BtnExit: TButton;
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure BtnSendClick(Sender: TObject);
        procedure BtnExitClick(Sender: TObject);
        procedure BtnStartClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        procedure OnUDPRecved(var ms: TMessage); message WM_UDPRECVED;
      end;var
      UDPForm: TUDPForm;implementation{$R *.dfm}var MsgIn, MsgOut: string;
        UDPSock: TUDPBlockSocket;
        UDPRecv: TUDPRecvThread;
        UDPSend: TUDPSendThread;
        Sending: Boolean;    procedure TUDPRecvThread.Execute;
    var m, n: Integer;
        s: string;
    begin
      FreeOnTerminate := True;
      while not Terminated do
      begin
        MsgIn := UDPSock.RecvPacket(3000);
        if UDPSock.LastError = 0 then
        begin
          if MsgIn[1] = 'R' then
          begin
            Delete(MsgIn, 1, 1);
            Val(MsgIn, m, n);
            if n = 0 then PostMessage(UDPForm.Handle, WM_UDPRECVED, m, 0);
          end
          else if MsgIn[1] = 'M' then
          begin
            Delete(MsgIn, 1, 1);
            n := Pos('M', MsgIn);
            if n > 0 then
            begin
              s := 'R' + Copy(MsgIn, 1, n - 1);
              Delete(MsgIn, 1, n);
              MsgIn := '*[' + UDPSock.GetRemoteSinIP + ':' + IntToStr(UDPSock.GetRemoteSinPort)
                       + ']' + MsgIn;
              UDPSock.SendBufferTo(@s[1], Length(s));
              PostMessage(UDPForm.Handle, WM_UDPRECVED, -1, 0);
              Suspend;
            end;
          end;
        end;
      end;
      UDPRecv := nil;
    end;procedure TUDPSendThread.Execute;
    var ms: MSG;
    begin
      FreeOnTerminate := True;
      while not Terminated do
      begin
        GetMessage(ms, 0, 0, 0);
        case ms.message of
          WM_UDPDOSEND:
          begin
            if Length(MsgOut) > 0 then with UDPSock, UDPForm do
            begin
              SocksIp := EdAddrSocks.Text;
              SocksPort := EdPortSocks.Text;
              SocksUsername := EdUsername.Text;
              SocksPassword := EdPassword.Text;
              Connect(EdAddrTo.Text, EdPortTo.Text);
              SendString(MsgOut);
              Sending := False;
            end;
          end;
          WM_TERMINATE: Terminate;
        end;
      end;
      UDPSend := nil;
    end;procedure TUDPForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      BtnExitClick(Sender);
      Action := caFree;
    end;procedure TUDPForm.BtnSendClick(Sender: TObject);
    var n: Integer;
    begin
      if Sending then
      begin
        ShowMessage('上一条消息还未发送完成,请稍候!');
        Exit;
      end;
      Sending := True;
      n := ListMsg.Count;
      MsgOut := 'M' + IntToStr(n) + 'M' + EdMsg.Text;
      ListMsg.Items.Append('-[' + EdAddrTo.Text + ':' + EdPortTo.Text + ']' + EdMsg.Text);
      PostThreadMessage(UDPSend.ThreadID, WM_UDPDOSEND, 0, 0);
    end;procedure TUDPForm.OnUDPRecved(var ms: TMessage);
    var s: string;
    begin
      if ms.WParam < 0 then
      begin
        ListMsg.Items.Append(MsgIn);
        UDPRecv.Resume;
        Exit;
      end;
      s := ListMsg.Items[ms.WParam];
      s[1] := '+';
      ListMsg.Items[ms.WParam] := s;
    end;procedure TUDPForm.BtnExitClick(Sender: TObject);
    begin
      if Assigned(UDPRecv) then UDPRecv.Terminate;
      if Assigned(UDPSend) then PostThreadMessage(UDPSend.ThreadID, WM_TERMINATE, 0, 0);
      while Assigned(UDPRecv) do Sleep(100);
      while Assigned(UDPSend) do Sleep(100);
      if Assigned(UDPSock) then
      begin
        UDPSock.CloseSocket;
        UDPSock.Free;
        UDPSock := nil;
      end;
      BtnStart.Enabled := True;
      EdMsg.Enabled := False;
      BtnSend.Enabled := False;
      EdPortLocal.Enabled := True;
      BtnExit.Enabled := False;
    end;procedure TUDPForm.BtnStartClick(Sender: TObject);
    begin
      BtnStart.Enabled := False;
      Sending := False;
      UDPSock := TUDPBlockSocket.Create;
      with UDPSock do Bind(ResolveName(LocalName), EdPortLocal.Text);
      UDPRecv := TUDPRecvThread.Create(False);
      UDPSend := TUDPSendThread.Create(False);
      EdMsg.Enabled := True;
      BtnSend.Enabled := True;
      EdPortLocal.Enabled := False;
      BtnExit.Enabled := True;  
    end;procedure TUDPForm.FormCreate(Sender: TObject);
    begin
      UDPRecv := nil;
      UDPSend := nil;
      UDPSock := nil;
      BtnStart.Enabled := True;
      EdMsg.Enabled := False;
      BtnSend.Enabled := False;
      EdPortLocal.Enabled := True;
      BtnExit.Enabled := False;
    end;end.
      

  3.   

    其实 用UDP只是来发送些行情而已,因为是实时在发,不一定要用TCP的拉
    再想问下,如何开多线程?
      

  4.   

    我以前测试的时候写过一个程序,在两台机器上运行可以相互发消息。发送和接收的消息都保存在一个listbox里,接收到的消息以*号开头,发送的消息以-号开头,发出的消息如果对方有回应,前面的-号变成+号。unit UdpMain;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls, blcksock;const
      WM_TERMINATE = WM_USER + 1;
      WM_UDPDOSEND = WM_USER + 2;
      
      WM_UDPRECVED = WM_USER + 51;type
      TUDPRecvThread = class(TThread)
      public
        procedure Execute; override;
      end;  TUDPSendThread = class(TThread)
      public
        procedure Execute; override;
      end;  TUDPForm = class(TForm)
        Label1: TLabel;
        ListMsg: TListBox;
        EdAddrTo: TEdit;
        Label2: TLabel;
        EdPortTo: TEdit;
        Label3: TLabel;
        Panel1: TPanel;
        Label4: TLabel;
        Label5: TLabel;
        EdAddrSocks: TEdit;
        Label6: TLabel;
        EdPortSocks: TEdit;
        Label7: TLabel;
        EdUserName: TEdit;
        Label8: TLabel;
        EdPassword: TEdit;
        BtnSend: TButton;
        Label9: TLabel;
        EdMsg: TEdit;
        Label10: TLabel;
        EdPortLocal: TEdit;
        BtnStart: TButton;
        BtnExit: TButton;
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure BtnSendClick(Sender: TObject);
        procedure BtnExitClick(Sender: TObject);
        procedure BtnStartClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        procedure OnUDPRecved(var ms: TMessage); message WM_UDPRECVED;
      end;var
      UDPForm: TUDPForm;implementation{$R *.dfm}var MsgIn, MsgOut: string;
        UDPSock: TUDPBlockSocket;
        UDPRecv: TUDPRecvThread;
        UDPSend: TUDPSendThread;
        Sending: Boolean;    procedure TUDPRecvThread.Execute;
    var m, n: Integer;
        s: string;
    begin
      FreeOnTerminate := True;
      while not Terminated do
      begin
        MsgIn := UDPSock.RecvPacket(3000);
        if UDPSock.LastError = 0 then
        begin
          if MsgIn[1] = 'R' then
          begin
            Delete(MsgIn, 1, 1);
            Val(MsgIn, m, n);
            if n = 0 then PostMessage(UDPForm.Handle, WM_UDPRECVED, m, 0);
          end
          else if MsgIn[1] = 'M' then
          begin
            Delete(MsgIn, 1, 1);
            n := Pos('M', MsgIn);
            if n > 0 then
            begin
              s := 'R' + Copy(MsgIn, 1, n - 1);
              Delete(MsgIn, 1, n);
              MsgIn := '*[' + UDPSock.GetRemoteSinIP + ':' + IntToStr(UDPSock.GetRemoteSinPort)
                       + ']' + MsgIn;
              UDPSock.SendBufferTo(@s[1], Length(s));
              PostMessage(UDPForm.Handle, WM_UDPRECVED, -1, 0);
              Suspend;
            end;
          end;
        end;
      end;
      UDPRecv := nil;
    end;procedure TUDPSendThread.Execute;
    var ms: MSG;
    begin
      FreeOnTerminate := True;
      while not Terminated do
      begin
        GetMessage(ms, 0, 0, 0);
        case ms.message of
          WM_UDPDOSEND:
          begin
            if Length(MsgOut) > 0 then with UDPSock, UDPForm do
            begin
              SocksIp := EdAddrSocks.Text;
              SocksPort := EdPortSocks.Text;
              SocksUsername := EdUsername.Text;
              SocksPassword := EdPassword.Text;
              Connect(EdAddrTo.Text, EdPortTo.Text);
              SendString(MsgOut);
              Sending := False;
            end;
          end;
          WM_TERMINATE: Terminate;
        end;
      end;
      UDPSend := nil;
    end;procedure TUDPForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      BtnExitClick(Sender);
      Action := caFree;
    end;procedure TUDPForm.BtnSendClick(Sender: TObject);
    var n: Integer;
    begin
      if Sending then
      begin
        ShowMessage('上一条消息还未发送完成,请稍候!');
        Exit;
      end;
      Sending := True;
      n := ListMsg.Count;
      MsgOut := 'M' + IntToStr(n) + 'M' + EdMsg.Text;
      ListMsg.Items.Append('-[' + EdAddrTo.Text + ':' + EdPortTo.Text + ']' + EdMsg.Text);
      PostThreadMessage(UDPSend.ThreadID, WM_UDPDOSEND, 0, 0);
    end;procedure TUDPForm.OnUDPRecved(var ms: TMessage);
    var s: string;
    begin
      if ms.WParam < 0 then
      begin
        ListMsg.Items.Append(MsgIn);
        UDPRecv.Resume;
        Exit;
      end;
      s := ListMsg.Items[ms.WParam];
      s[1] := '+';
      ListMsg.Items[ms.WParam] := s;
    end;procedure TUDPForm.BtnExitClick(Sender: TObject);
    begin
      if Assigned(UDPRecv) then UDPRecv.Terminate;
      if Assigned(UDPSend) then PostThreadMessage(UDPSend.ThreadID, WM_TERMINATE, 0, 0);
      while Assigned(UDPRecv) do Sleep(100);
      while Assigned(UDPSend) do Sleep(100);
      if Assigned(UDPSock) then
      begin
        UDPSock.CloseSocket;
        UDPSock.Free;
        UDPSock := nil;
      end;
      BtnStart.Enabled := True;
      EdMsg.Enabled := False;
      BtnSend.Enabled := False;
      EdPortLocal.Enabled := True;
      BtnExit.Enabled := False;
    end;procedure TUDPForm.BtnStartClick(Sender: TObject);
    begin
      BtnStart.Enabled := False;
      Sending := False;
      UDPSock := TUDPBlockSocket.Create;
      with UDPSock do Bind(ResolveName(LocalName), EdPortLocal.Text);
      UDPRecv := TUDPRecvThread.Create(False);
      UDPSend := TUDPSendThread.Create(False);
      EdMsg.Enabled := True;
      BtnSend.Enabled := True;
      EdPortLocal.Enabled := False;
      BtnExit.Enabled := True;  
    end;procedure TUDPForm.FormCreate(Sender: TObject);
    begin
      UDPRecv := nil;
      UDPSend := nil;
      UDPSock := nil;
      BtnStart.Enabled := True;
      EdMsg.Enabled := False;
      BtnSend.Enabled := False;
      EdPortLocal.Enabled := True;
      BtnExit.Enabled := False;
    end;end.这种方法是不安全的!!
    你可以建立一个服务器端和一个客户端,然后进行互相传!!
      

  5.   

    对啊,要采用多线程,高手,指点一下啊!
    实时发送要用TIMER控件吗?