有些问题想请教大家,我用Delphi做一个上位机软件,要和下位机通讯。当socket收到数据时,做出响应。(每次接受到数据都向下位机发送指令),这样的功能该如何做?WinSock能不能实现像事件驱动那样的功能,一有数据达到就能进行相应的处理。我看了WSAAsyncSelect函数,可是不明白WM_SOCKET是一个什么样的消息,自定义的?本人菜鸟,谢谢大家。

解决方案 »

  1.   

    1.WinSock能不能实现像事件驱动那样的功能? ——WinSock是一组WindowsApi,你把它封装成对象,自己加事件就可以了呗;
    2.WM_SOCKET应该是delphi预定义的吧;如果是菜鸟的话还是找本书看吧~
      

  2.   

    如果压力不大,使用tcpserver这样的标准控件,都是有事件的
      

  3.   

    上位机是PC机,下位机是单片机? 如果是这样,PC机与单片机之间怎么用Winsocket通信?Winsocket是Windows操作系统中的概念,而单片机哪来的Windows ?PC与单片机之间常用串口进行通信,在Delphi中可以使用很多第三方的串口通信控件,如:Comport等。
      

  4.   

    先去看看windows网络编程 虽然是c的 但是里面介绍的很清楚 
      

  5.   

    给你个简单的例子,适合新人参考
    --------------------点对点文件传输--------------------------- 采用的协议: 
    首先由Client发送MP_QUERY,Server接受到后发送MP_ACCEPT或MP_FEFUESE; 
    Client接受到MP_ACCEPT发送MP_FILEPROPERTY,Server接受到后发送MP_NEXTWILLBEDATA; 
    Client接受到发送MP_NEXTWILLBEDATA,Server接受到后发送MP_DATA; 
    Client接受到MP_DATA,发送数据块,Server接受数据块, 
    Server还没接受完,发送MP_NEXTWILLBEDATA,否则发送MP_END 
    Client接受MP_END后,向Server发送MP_END; 
    Server收到MP_END后,停止发送。至此,整个文件传输完毕! 
    ----------------------服务器端---------------------------- 
    unit Unit1; interface uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, ScktComp, StdCtrls; 
    Const 
    MP_QUERY ='1'; 
    MP_REFUSE ='2'; 
    MP_ACCEPT ='3'; 
    MP_NEXTWILLBEDATA='4'; 
    MP_DATA ='5'; 
    MP_ABORT ='6'; 
    MP_OVER ='7'; 
    MP_CHAT ='8'; 
    MP_END ='9'; 
    MP_FILEPROPERTY ='0'; 
    iBYTEPERSEND=1024; 
    type 
    TForm1 = class(TForm) 
    btnstartServer: TButton; 
    Edit1: TEdit; 
    Edit2: TEdit; 
    ss: TServerSocket; 
    SaveDialog1: TSaveDialog; 
    Memo1: TMemo; 
    Button1: TButton; 
    Edit3: TEdit; 
    procedure btnstartServerClick(Sender: TObject); 
    procedure ssClientConnect(Sender: TObject; Socket: TCustomWinSocket); 
    procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket); 
    procedure ssClientError(Sender: TObject; Socket: TCustomWinSocket; 
    ErrorEvent: TErrorEvent; var ErrorCode: Integer); 
    procedure Button1Click(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    private 
    fsRecv:TMemoryStream; 
    public 
    { Public declarations } 
    end; var 
    Form1: TForm1; 
    bReadText:boolean; 
    implementation {$R *.dfm} procedure TForm1.btnstartServerClick(Sender: TObject); 
    begin 
    ss.Port:=2000; 
    bReadText := true; 
    Edit1.Text:='Server is listening'; 
    ss.Open; 
    end; procedure TForm1.ssClientConnect(Sender: TObject; 
    Socket: TCustomWinSocket); 
    begin 
    Edit1.Text:='Server is connected by'+Socket.RemoteAddress; 
    end; procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket); 
    var 
    sTemp:string; 
    bufRecv:Pointer; 
    iNum:integer; 
    begin 
    Memo1.Lines.Add('received size :' + intToStr(Socket.ReceiveLength)); 
    if bReadText then 
    begin 
    sTemp:=Socket.ReceiveText; 
    case sTemp[1] of 
    MP_QUERY: 
    begin 
    Memo1.Lines.Add('receive MP_QUERY'); 
    SaveDialog1.FileName:=Copy(sTemp,2,Length(STemp)); 
    if SaveDialog1.Execute then 
    begin 
    // ss.Socket.SendText(MP_ACCEPT); 
    ss.Socket.Connections[0].SendText(MP_ACCEPT); fsRecv := TMemoryStream.Create; 
    // fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate); 
    edit2.Text := SaveDialog1.FileName; 
    end 
    else 
    ss.Socket.Connections[0].SendText(MP_REFUSE+' '); 
    end; 
    MP_FILEPROPERTY: 
    begin 
    Memo1.Lines.Add('receive MP_FILEPROPERTY'); 
    ss.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA); 
    end; 
    MP_NEXTWILLBEDATA: 
    begin 
    Memo1.Lines.Add('receive MP_NEXTWILLBEDATA'); 
    bReadText:=false; 
    ss.Socket.Connections[0].SendText(MP_DATA); 
    end; 
    MP_END: 
    begin 
    Memo1.Lines.Add('receive MP_END'); 
    fsRecv.Free; 
    bReadText:=true; 
    end; 
    MP_ABORT: 
    begin 
    Memo1.Lines.Add('receive MP_ABORT'); 
    fsRecv.Free; 
    bReadText:=true; 
    end; 
    MP_CHAT: 
    begin 
    Memo1.Lines.Add('receive MP_CHAT'); 
    end; 
    end;{of case} 
    end 
    else 
    begin 
    try GetMem(bufRecv, iBYTEPERSEND); 
    iNum := Socket.ReceiveBuf(bufRecv^, iBYTEPERSEND); 
    fsRecv.WriteBuffer(bufRecv^, iNum); 
    finally 
    FreeMem(bufRecv); 
    end;{of try} 
    bReadText:=true; if iNum = iBYTEPERSEND THEN 
    begin 
    ss.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA); 
    end 
    else 
    begin 
    fsRecv.SaveToFile(SaveDialog1.FileName); 
    fsRecv.Free; 
    ss.Socket.Connections[0].SendText(MP_END); 
    end; 
    end; 
    end; 
    procedure TForm1.ssClientError(Sender: TObject; Socket: TCustomWinSocket; 
    ErrorEvent: TErrorEvent; var ErrorCode: Integer); 
    begin 
    Memo1.Lines.Add('ErrorCode :' + IntToStr(ErrorCode)); 
    ErrorCode := 0; 
    end; procedure TForm1.Button1Click(Sender: TObject); 
    var I, j: integer; 
    begin 
    J := ss.Socket.ActiveConnections; 
    Memo1.Lines.Add('ActiveConnectiong is ' + inttostr(j)); 
    for I:= 0 to j- 1 do 
    ss.Socket.Connections[i].SendText(edit3.Text) 
    end; procedure TForm1.FormCreate(Sender: TObject); 
    begin 
    ss.Port:=2000; 
    bReadText := true; 
    Edit1.Text:='Server is listening'; 
    ss.Open; 
    end; 
    end. ----------------------客户端---------------------------- 
    unit clientSocketu; interface uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, ScktComp; 
    Const 
    MP_QUERY ='1'; 
    MP_REFUSE ='2'; 
    MP_ACCEPT ='3'; 
    MP_NEXTWILLBEDATA='4'; 
    MP_DATA ='5'; 
    MP_ABORT ='6'; 
    MP_OVER ='7'; 
    MP_CHAT ='8'; 
    MP_END ='9'; 
    MP_FILEPROPERTY ='0'; 
    iBYTEPERSEND=1024; 
    type 
    TForm1 = class(TForm) 
    btnConnect: TButton; 
    btnSendFile: TButton; 
    Edit1: TEdit; 
    Edit2: TEdit; 
    cs: TClientSocket; 
    Label1: TLabel; 
    edtIPAddress: TEdit; 
    edtSize: TEdit; 
    OpenDialog1: TOpenDialog; 
    Memo1: TMemo; 
    procedure btnConnectClick(Sender: TObject); 
    procedure btnSendFileClick(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure csRead(Sender: TObject; Socket: TCustomWinSocket); 
    private 
    fsSend:TFileStream; 
    public 
    { Public declarations } 
    end; var 
    Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btnConnectClick(Sender: TObject); 
    begin 
    cs.Address := edtIPAddress.Text; 
    cs.Port:=2000; 
    cs.Open; 
    end; procedure TForm1.btnSendFileClick(Sender: TObject); 
    begin 
    if OpenDialog1.Execute then 
    Begin 
    cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName); 
    end; 
    end; procedure TForm1.FormCreate(Sender: TObject); 
    begin 
    edit1.Color:=clBlack; 
    edit1.Font.Color:=clLime; 
    end; procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket); 
    var 
    sRecv:string; 
    // sTemp:string; 
    iNum:integer; 
    bufSend:pointer; 
    begin 
    // GetMem(bufSend,iBytePersend+1); 
    sRecv:=Socket.ReceiveText; 
    Memo1.Lines.Add('sRecv = ' + sRecv); 
    Case sRecv[1] of 
    MP_REFUSE:ShowMessage('Faint,be refused!'); 
    MP_ACCEPT:begin 
    Memo1.Lines.Add('MP_ACCEPT'); 
    fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead); edtSize.Text:=IntToStr(fsSend.Size); 
    edit2.text:='total count:'+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1); cs.Socket.SendText(MP_FILEPROPERTY+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1)); 
    fsSend.Seek(0, soFromBeginning); 
    end; 
    MP_NEXTWILLBEDATA:begin 
    Memo1.Lines.Add('MP_NEXTWILLBEDATA'); 
    Socket.SendText(MP_NEXTWILLBEDATA); 
    end; 
    MP_DATA: 
    begin 
    Memo1.Lines.Add('MP_DATA'); 
    try 
    GetMem(bufSend, iBYTEPERSEND); 
    iNum := fsSend.Read(bufSend^, iBYTEPERSEND); 
    cs.Socket.SendBuf(bufSend^, iNum); 
    // Socket.SendBuf(bufSend,iNum); 
    Memo1.Lines.Add('Send Buf finished'); 
    finally 
    FreeMem(bufSend); 
    end;{of try} 
    end; 
    MP_END: 
    begin 
    Memo1.Lines.Add('MP_END'); 
    fsSend.Free; 
    end; 
    MP_ABORT:begin 
    Memo1.Lines.Add('MP_ABORT'); 
    fsSend.Free; 
    end; 
    end;{of case} 
    end; 
    end.   
      

  6.   

    WM_SOCKET要自定义消息
    Indy控件是阻塞的
    TServerSocket控件 是非阻塞的如果不熟socket,还是直接用控件好一些