Конференция "Сети" » Асинхронные сокеты [D7, WinXP]
 
  • prodex (07.03.08 09:45) [0]
    Доброго времени суток, Мастера;
    Есть код:

    unit Unit1;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, WinSock, Sockets, StdCtrls;

    const
     WM_SSocketEvent=WM_User+1;
     WM_CSocketEvent=WM_User+2;

    type
     TForm1 = class(TForm)
       Button1: TButton;
       Label1: TLabel;
       procedure FormCreate(Sender: TObject);
       procedure FormDestroy(Sender: TObject);
       procedure Button1Click(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
       ServSock   :TSocket;
       ClntSock   :TSocket;
       s : string;
       procedure WMSSocketEvent(var Msg:TMessage);message WM_SSocketEvent;
       procedure WMCSocketEvent(var Msg:TMessage);message WM_CSocketEvent;
     end;

    var
     Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.FormCreate(Sender: TObject);
    var
    Data:TWSAData;
    Addr:TSockAddr;
    begin
      WSAStartup($101,Data);
      ClntSock:=Socket(AF_Inet,SOCK_DGRAM,0);
      Addr.sin_family:=AF_Inet;
      Addr.sin_addr.S_addr:=Inet_Addr('10.122.1.2');
      Addr.sin_port:=HToNS(4000);
      FillChar(Addr.sin_zero,SizeOf(Addr.sin_zero),0);
      WSAAsyncSelect(ClntSock,Handle,
                     WM_SSocketEvent,FD_Read or FD_Accept or FD_Close);

      ServSock:=Socket(AF_Inet,SOCK_DGRAM,0);
      Addr.sin_family:=AF_Inet;
      Addr.sin_addr.S_addr:=Inet_Addr('10.122.1.10');//InAddr_Any;
      Addr.sin_port:=HToNS(4000);
      FillChar(Addr.sin_zero,SizeOf(Addr.sin_zero),0);
      WSAAsyncSelect(ServSock,Handle,
                     WM_SSocketEvent,FD_Read or FD_Accept or FD_Close);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
     CloseSocket(ServSock);
     WSACleanup;
    end;

    procedure TForm1.WMCSocketEvent(var Msg:TMessage);
    begin
    ShowMessage('sdfssdf');
    end;

    procedure TForm1.WMSSocketEvent(var Msg:TMessage);
    var Sock:TSocket;
       SockError:Integer;
    begin
      Sock:=TSocket(Msg.WParam);
      SockError:=WSAGetSelectError(Msg.lParam);
      if SockError<>0 then
       begin
        CloseSocket(Sock);
        Exit
       end;
      case WSAGetSelectEvent(Msg.lParam) of
       FD_Read:
        begin
         SetLength(s,20);
         recv(Sock,s,20,0);
         Label1.Caption:=s;
    //      ShowMessage(s);
        end;
       FD_Accept:
        begin
         Accept(Sock,nil,nil)
        end;
       FD_Close:
        begin
         Shutdown(Sock,SD_Send);
         CloseSocket(Sock)
        end
      end
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    str : string;
    Addr:TSockAddr;
    begin
    str:='0123456789';
    Addr.sin_family:=AF_Inet;
    Addr.sin_addr.S_addr:=Inet_Addr('10.122.1.10');
    Addr.sin_port:=HToNS(4000);
    Connect(ClntSock,Addr,SizeOf(Addr));
    Send(ClntSock,str,10,0);
    end;

    end.

    Сообщение передает и принимает, но по завершении программы выдает ошибку "Access violation...". Если вставить ShowMessage сразу после recv тогда выдает ту же ошибку сразу после ShowMessage (кстати такая же ситуация при использовании стандартных TClientSocket и TServerSocket в неблокирующем режиме).
    И еще вопрос: можно ли привязать слушающий асинхронный сокет, т.е. я так понял сервер, и клиентский к одному и тому же IP и порту через Win API?
  • Сергей М. © (07.03.08 09:55) [1]
    Эт чего вообще такое у тебя - клиент или сервер ?
    Судя по коду - винегрет непонятного вкуса)


    > можно ли привязать слушающий асинхронный сокет, т.е. я так
    > понял сервер, и клиентский к одному и тому же .. порту


    А собссно зачем ?
  • Сергей М. © (07.03.08 10:00) [2]

    > кстати такая же ситуация при использовании стандартных TClientSocket
    > и TServerSocket в неблокирующем режиме



    > Send(ClntSock,str,10,0);


    > recv(Sock,s,20,0);


    Ошибка - в выделенном. Грубая причем.

    И режим тут совершенно ни при чем, как и собственно сокеты.

    Посмотри внимательно на прототип этих функций (!!!!!) в части выделенных параметров.
  • prodex (07.03.08 10:10) [3]
    >Эт чего вообще такое у тебя - клиент или сервер ?
    >Судя по коду - винегрет непонятного вкуса)


    Инициатором передачи являются обе машины
  • Сергей М. © (07.03.08 10:12) [4]

    > Инициатором передачи являются обе машины


    Причем здесь инициация передачи ?

    Зачем у тебя в программе и клиентская и серверная часть одновременно ?

    И если серверная таки нужна, то где вызов listen() ?
  • prodex (07.03.08 10:30) [5]
    Посмотрел прототип: char FAR* buf, как интерпретировать это в Дельфи?
  • Сергей М. © (07.03.08 10:38) [6]
    При buf:String правильными будут варианты:

    1. PChar(buf)^
    2. buf[1]
    3. @buf[1]
 
Конференция "Сети" » Асинхронные сокеты [D7, WinXP]
Есть новые Нет новых   [134431   +14][b:0][p:0]