• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

            路漫漫,長修遠,我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
            數據加載中……

            [導入]終于搞定了異步通信了,調試了兩天,發現偶還素犯了一個弱智錯誤

            我把client的socket初始化內容寫在了message響應函數里面了,每次觸發消息的時候就把客戶端的socket置0了

             

            服務器端代碼如下:

            由于比較簡單,所以不貼注釋了,如果有什么不懂d地方,大家對著翻吧

             

            unit Listener;

            interface

            uses
              SysUtils,  Controls, Forms, winsock, Classes, ComCtrls, StdCtrls;


            const ASYNC_EVENT = $0400 + 1;
              SO_CONDITIONAL_ACCEPT = $3002;
            type

              TCMSocketMessage = record //select 消息結構
                Msg: Cardinal; //系統消息
                Socket: TSocket; //產生消息的源socket 句柄
                SelectEvent: Word; //select消息
                SelectError: Word; //錯誤
                Result: Longint;
              end;

             

            type
              TMain = class(TForm)
                SBar: TStatusBar;
                Memo1: TMemo;
                procedure FormDestroy(Sender: TObject);
                procedure FormCreate(Sender: TObject);
              private
                s: TSocket;
                SClinent: TSocket;
                procedure bindAddr;
                procedure CMIncCount(var Msg: TCMSocketMessage); message ASYNC_EVENT;
                procedure listenAddr;
                { Private declarations }
              public
                { Public declarations }
              end;

            var
              Main: TMain;

            implementation

            {$R *.dfm}

            procedure TMain.FormDestroy(Sender: TObject);
            begin
              closeSocket(s);
              WSACleanup();
            end;

            procedure TMain.FormCreate(Sender: TObject);
            var
              wsa: TWSaData;
              flag: integer;
            begin
              SClinent := 0;
              //SysUtils.BoolToStr()
              flag := WSAStartup($0202, wsa); //加載winsock
              if flag <> 0 then begin
                SBar.Panels[2].Text := format('錯誤號:%d', [WSAGetLastError()]);
                SBar.Panels[1].Text := 'Winsock庫加載失敗';
              end;

              bindAddr;
              listenAddr;
            end;


            procedure TMain.bindAddr;
            var
              addr: TSockAddrIn;
              flag: integer;
            begin
              s := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //服務器端的socket
              addr.sin_port := htons(45531);
              addr.sin_family := AF_INET;
              addr.sin_addr.S_addr := INADDR_ANY; //inet_addr(pchar(host));

              flag := bind(s, addr, sizeof(addr));
              if flag = SOCKET_ERROR then begin
                SBar.Panels[2].Text := format('錯誤號:%d', [WSAGetLastError()]);
                SBar.Panels[1].Text := 'IP綁定錯誤';
              end else begin
                flag := WSAAsyncSelect(s, Handle, ASYNC_EVENT, FD_ACCEPT or FD_CONNECT or FD_CLOSE or FD_READ or FD_WRITE);
                if flag = SOCKET_ERROR then begin
                  SBar.Panels[2].Text := format('錯誤號:%d', [WSAGetLastError()]);
                  SBar.Panels[1].Text := 'WSAAsyncSelect錯誤';
                end;
              end;
            end;

            procedure TMain.listenAddr;
            var flag: integer;
            begin
              flag := listen(s, 10);
              if flag = SOCKET_ERROR then begin
                SBar.Panels[2].Text := format('錯誤號:%d', [WSAGetLastError()]);
                SBar.Panels[1].Text := '監聽失敗';
              end;
            end;

             

            procedure TMain.CMIncCount(var Msg: TCMSocketMessage);
            var
              addr: TSockAddrIn;
              len: integer;
              SendBuf: array[1..1024] of AnsiChar;
              recvBuf: array[1..1024] of AnsiChar;
              str: string;
              OldOpenType {, NewOpenType}: integer;
            begin
              len := 0;

              str := '';

              case Msg.SelectEvent of
                FD_READ: begin
                    len := sizeof(recvBuf);
                    ioctlsocket(SClinent, FIONREAD, Longint(len));
                    fillchar(recvBuf, sizeof(recvBuf), 0);
                    recv(SClinent, recvBuf, sizeof(recvBuf), 0);

                    Memo1.Lines.Add(string(recvBuf));
                    Memo1.Lines.Add('read');
                    if Memo1.Lines.Count > 10 then
                      memo1.Clear;

                    sleep(10);
                    fillchar(SendBuf, sizeof(SendBuf), 0);
                    Strcopy(@SendBuf, pansichar('OK'));
                    Send(SClinent, sendbuf, sizeof(sendbuf), 0);
                  end;

                FD_WRITE: begin


                    Memo1.Lines.Add('write');
                  end;
                FD_ACCEPT: begin
                    len := sizeof(OldOpenType);

                    if getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, PChar(@OldOpenType), len) = 0 then begin
                      try
                        len := sizeof(addr);
                        SClinent := accept(s, @addr, @len);

                        if SClinent = INVALID_SOCKET then begin
                          Memo1.Lines.Add('無效的socket:' + inttostr(SClinent));
                        end;
                        Memo1.Lines.Add('accept');
                      finally
                        len := sizeof(OldOpenType);
                        setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, PChar(@OldOpenType), len);
                      end;
                    end;
                    WSAAsyncSelect(SClinent, handle, ASYNC_EVENT, $33);

                  end;
                FD_CONNECT: begin
                    Memo1.Lines.Add('connect');
                  end;
                FD_CLOSE: begin
                    Memo1.Lines.Add('close');
                  end;
              end;
            end;

            end.
            //由于服務器端沒有緩存機制,所以多個client連接的時候,第二個client的socket會覆蓋前一個的,大家看情況改改就行了,網絡上大把代碼都是用控件或者其他封裝好d類來寫d,所以資料郁悶死了.

             

             

            客戶端代碼:

            program Client;

            {$APPTYPE CONSOLE}

            uses
              SysUtils,
              windows,
              winsock;

            var
              addr: TSockAddrIn;
              wsa: TWSaData;
              flag: integer;
              s: TSocket;
              Host: string;
              Port: Word;
              BufSend: array[1..1024] of Ansichar; //中間信息
              BufRev: array[1..1024] of Ansichar;
              i: Integer;
            begin
              { TODO -oUser -cConsole Main : Insert code here }

              Host := '127.0.0.1';
              port := 45531;

              flag := WSAStartup($0202, wsa); //加載winsock
              if flag <> 0 then begin
                Writeln(format('錯誤號:%d', [WSAGetLastError()]));
                Writeln('Winsock庫加載失敗');
              end else begin
                Writeln('Winsock庫加載成功')
              end;

              //s := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //服務器端的socket
              s := socket(PF_INET, SOCK_STREAM, 0);
              FillChar(addr, sizeof(addr), 0); //初始化地址空間

              addr.sin_port := htons(port);
              addr.sin_family := AF_INET;
              addr.sin_addr.S_addr := {INADDR_ANY; } inet_addr(pchar(host));

              if connect(s, addr, sizeof(addr)) = 0 then begin
                Writeln('主機:' + Host + ' 連接成功')
              end else begin
                Writeln('主機:' + Host + ' 連接失敗');
              end;

              FillChar(BufSend, 1024, 0);

              StrPCopy(@BufSend, '測試信息包');
              for i := 0 to 100 do begin
                Writeln(inttostr(s));
                if Send(s, Bufsend, Length(BufSend), 0) <> SOCKET_ERROR then begin
                  Writeln('消息已發送');
                  sleep(500);

                  FillChar(BufRev, 1024, 0);
                  //strcopy(bufsend,pansichar('a'))
                  if recv(s, BufRev, Length(BufSend), 0) <> SOCKET_ERROR then begin
                    writeln('接收到的信息:' + trim(string(BufRev)));
                  end else begin
                    Writeln('接收消息失敗!')
                  end;

                end else begin
                  Writeln('消息發送失敗')
                end;
              end;

             

              if closeSocket(s) = 0 then begin
                Writeln('已經關閉socket')
              end else begin
                Writeln('關閉socket 出錯')
              end;

              WSACleanup();
              Readln;
            end.

            posted on 2006-01-12 09:56 Khan 閱讀(1428) 評論(0)  編輯 收藏 引用 所屬分類: Delphi

            成人久久免费网站| 一本久久a久久精品综合夜夜| 久久久久99精品成人片| 久久国产视屏| 欧美午夜精品久久久久免费视| 久久久无码精品亚洲日韩按摩 | 7777久久亚洲中文字幕| 国产成人精品久久| 欧美国产成人久久精品| 久久精品国产久精国产| 国内精品久久久久影院亚洲| 久久精品国产91久久综合麻豆自制 | 久久综合九色综合网站| 久久狠狠色狠狠色综合| 一本色道久久99一综合| 四虎国产精品免费久久| 久久精品国产99国产电影网| 国内精品久久国产| 久久无码一区二区三区少妇 | 色综合久久综合网观看| 久久99国产综合精品| 久久精品免费一区二区| 午夜精品久久久久久久无码| 99热成人精品免费久久| 国产精品久久久久久久| 新狼窝色AV性久久久久久| 国产69精品久久久久观看软件| 嫩草影院久久99| 国产成人久久激情91| 国产精品美女久久久久久2018| 亚洲AV无码久久| 日韩精品久久久久久久电影蜜臀| 久久午夜无码鲁丝片秋霞| 老男人久久青草av高清| 亚洲&#228;v永久无码精品天堂久久 | 无码精品久久久天天影视 | 亚洲国产精品久久久久网站| 久久综合综合久久狠狠狠97色88| 久久99免费视频| 国产精品久久99| AAA级久久久精品无码区|