Q&A

  • function에서 procedure를 호출하려면 어떻게해야하죠?
function Tsendmsg2.Msendmsg2(const msg: WideString): WideString;

begin



clients.OnWrite(TObject, TCustomWinSocket);





end;



procedure Tsendmsg2.ClientSWrite(Sender: TObject; Socket: TCustomWinSocket);

begin

clients.Active := true;

socket.SendText('KwGwMGS RESERVE hanstay.com CPLOGINID checksum cpipcode svccode 211.117.100.142 1111');



end;

---------------------------------------------------



function에서 아래프로시져를 호출하기위해 function안에 위와같이 써줬는데 안돼네요..어떻게 불려야하는거죠?



부탁드립니다..



3  COMMENTS
  • Profile
    토맛토 2001.07.04 08:55
    sizzling wrote:

    > function Tsendmsg2.Msendmsg2(const msg: WideString): WideString;

    > begin

    >

    > clients.OnWrite(TObject, TCustomWinSocket);

    >

    >

    > end;

    >

    > procedure Tsendmsg2.ClientSWrite(Sender: TObject; Socket: TCustomWinSocket);

    > begin

    > clients.Active := true;

    > socket.SendText('KwGwMGS RESERVE hanstay.com CPLOGINID checksum cpipcode svccode 211.117.100.142 1111');

    >

    > end;

    > ---------------------------------------------------

    >

    > function에서 아래프로시져를 호출하기위해 function안에 위와같이 써줬는데 안돼네요..어떻게 불려야하는거죠?

    >

    > 부탁드립니다..

    >



    Msendmsg2함수를 호출하면 데이터가 전송되도록 하고자 하심인가요?

    OnWrite은 호출하도록 되어있는 함수가 아니고 데이터가 전송될 때 실행할 이벤트핸들러 프로시저에 대한 포인터입니다. 즉 프로시저가 아니고 프로퍼티이죠



    데이터를 보낼 때는 이렇게 해야 합니다.



    function Tsendmsg2.Msendmsg2(const msg: WideString): WideString;

    begin

    clients.Active := true; // 접속

    socket.SendText('KwGwMGS RESERVE hanstay.com CPLOGINID checksum cpipcode svccode 211.117.100.142 1111'); // 전송

    end;



    그리고 Tsendmsg2.ClientSWrite 에는 데이터가 전송될 때 처리하고자 하는 처리 코드를 넣습니다. (데이터전송중 메시지표시나 뭐 등등...)



    프로그램 초기화과정에서 Tsendmsg2.ClientSWrite가 OnWrite의 이벤트 핸들러가 되도록 다음과 같이 씁니다.

    Tsendmsg2.OnWrite = ClientSWrite;



    또는 클라이언트 소켓 속성창의 OnWrite를 클릭하여 ClientSWrite로 설정해 놓아도 됩니다.







  • Profile
    sizzling 2001.07.04 21:39
    com을 만드는것이라 Tclientsocket을 동적으로 생성시키고 asp에서 받은 msg를 socket로 쐈는데

    안쏴지더라구요..왜그럴까요?

    부탁드립니다. 꾸벅~

    ---------------------------------------------------------------------------------

    type

    clients: TClientSocket;



    function Tsendmsg2.Msendmsg2(const msg: WideString): WideString;

    begin

    clients := TClientSocket.Create(nil);

    clients.Address := '168.126.72.203';

    clients.port := 8600;

    clients.ClientType := ctNonBlocking;

    clients.Active := true;

    clients.socket.SendText(msg);

    result := clients.Socket.ReceiveText;

    clients.Active := false;

    end;



    ----------------------------------------------------------------------------------

  • Profile
    토맛토 2001.07.05 08:50
    sizzling wrote:

    > com을 만드는것이라 Tclientsocket을 동적으로 생성시키고 asp에서 받은 msg를 socket로 쐈는데

    > 안쏴지더라구요..왜그럴까요?

    > 부탁드립니다. 꾸벅~

    > ---------------------------------------------------------------------------------

    > type

    > clients: TClientSocket;

    >

    > function Tsendmsg2.Msendmsg2(const msg: WideString): WideString;

    > begin

    > clients := TClientSocket.Create(nil);

    > clients.Address := '168.126.72.203';

    > clients.port := 8600;

    > clients.ClientType := ctNonBlocking;

    > clients.Active := true;

    > clients.socket.SendText(msg);

    > result := clients.Socket.ReceiveText;

    > clients.Active := false;

    > end;

    >

    > ----------------------------------------------------------------------------------





    우선 이런 형태의 로직을 구현하려면 TClientSocket의 ClientType이 ctNonBlocking으로 하시면 곤란합니다.

    clients.Active; --> 이부분에서 접속을 시도하는데 ctNonBlocking은 접속이 되는지 기다리지 않고 그냥 지나가도록 합니다. (NonBlocking이란 말뜻을 잘 생각해 보시옵소서)



    대부분 접속이 이루어 지는 시점은 약간이 시간이 소요되기 때문에 접속이 채 이루어 지기 전에 clients.socket.SendText(msg); 가 실행됩니다.



    SendText명령도 역시 전송결과를 기다리지 않고 result := clients.Socket.ReceiveText;까지 갑니다.

    물론 SendText에 전달된 문자열은 접속이 이루어 지기 전까지는 소켓객체의 버퍼에 남아 있겠지만 접속이 아무리 빨리 이루어 지더라도 분명히 접속되기 전에 위의 함수의 모든 코드가 지나가 버리고 맙니다. 실제로 데이터가 보내지거나 받기전에 말이죠



    또한 중요한 것은 clients.Socket.ReceiveText; --> 이명령은 위에 기술하신 것처럼 사용하지 않습니다. 받드시 소켓의 OnRead메소드 안에서 실행되야 합니다.

    왜냐하면 ReceiveText는 메시지를 받을 때까지 기다리는 것이 아니고 현재 도착된 데이터가 있는지 보고 없으면 그냥 지나가기 때문이죠. 따라서 데이터가 전송되어 오는 시점인 OnRead이벤트가 발생되었을 때만 올바르게 데이터를 받을 수 있습니다.



    제작하시고자 하는 것이 ASP컴포넌트이니까 이벤트를 감지한다기 보다 모든 코드가 순차적으로 이루어지고 객체가 해제되어야겠죠

    ClientType을 Blocking으로 하시면 Active명령에서 접속이 될때 까지 현재의 스레드가 블럭킹됩니다.

    접속이 이루어 지면 다음으로 넘어가죠. 접속이 실패하는 경우도 있을 테니까 예외처리 하셔야 할 거구요...



    SendText에서 메시지를 보냅니다.



    그다음 전송되어오는 응답을 읽어야 하는데 Blocking으로 할 경우 ReceiveText가 아니고 TWinSocketStream클래스의 Read명령을 써야 합니다. 이것은 메시지가 올 때까지 기다립니다.(또한 Blocking으로 하는 경우 OnRead,OnWrite등의 이벤트는 감지되지 않습니다. 전부 스레드로 별도 제작해야 합니다.)



    이런식으로... 델파이 도움말이 있는 예제입니다.





    var

    Stream : TWinSocketStream;

    Buffer : array[0 .. 9] of Char; // 데이터 받을 버퍼

    begin





    try

    Stream := TWinSocketStream.Create(ClientSocket, 60000); // 타임아웃을 1분으로 하는 소켓 스트림

    try

    FillChar(Buffer, 10, 0);



    if Stream.WaitForData(60000) then // 1분동안 데이터를 기다림

    begin

    if Stream.Read(Buffer, 10) = 0 then // 1분이 지나가 버렸다면

    ClientSocket.Close; // 소켓을 닫는다.



    // 1분안에 데이터가 도착했다면 처리한다.



    end

    else

    ClientSocket.Close; { if client doesn