Q&A

  • client socket과 server socket
안녕하세요.



1대의 PC에서 여러대의 PC로 메세지를 전송하는 프로그램을 작성중입니다.

1:1로는 잘 되는데



for문을 이용하여

1:여러대로 전송하려면 마지막 PC에만 전송이 되고 다른 PC에는

"Asynchronous socket error"가 나면서 전송이 되지 않습니다.



보내는 프로그램에는 TClientSocket을 사용했고

받는 프로그램에는 TServerSocket을 사용하였습니다.



ClientSocket에서는 다중연결을 지원하지 않아서 그런건지 아니면

for문으로 돌기때문에 그런건지



아뭏든 어떻게든 해결을 해야하는데 방법을 모르겠습니다.



for i := 1 to query2.recordcount do

begin

if ClientSocket.Active then

ClientSocket.Active := False;



server := query2.fieldbyname('login_ip').asstring;

if Length(Server) > 0 then

begin

clientsocket.address := server;

clientsocket.Active := true;

succ_count := succ_count + 1;

end;

query2.next;

end;



자세한 설명 좀 부탁드립니다. 감사합니다.



2  COMMENTS
  • Profile
    구창민 1999.09.07 04:32
    한경아 께서 말씀하시기를...

    > 안녕하세요.

    >

    > 1대의 PC에서 여러대의 PC로 메세지를 전송하는 프로그램을 작성중입니다.

    > 1:1로는 잘 되는데

    >

    > for문을 이용하여

    > 1:여러대로 전송하려면 마지막 PC에만 전송이 되고 다른 PC에는

    > "Asynchronous socket error"가 나면서 전송이 되지 않습니다.

    >

    > 보내는 프로그램에는 TClientSocket을 사용했고

    > 받는 프로그램에는 TServerSocket을 사용하였습니다.

    >

    > ClientSocket에서는 다중연결을 지원하지 않아서 그런건지 아니면

    > for문으로 돌기때문에 그런건지

    >

    > 아뭏든 어떻게든 해결을 해야하는데 방법을 모르겠습니다.

    >

    > for i := 1 to query2.recordcount do

    > begin

    > if ClientSocket.Active then

    > ClientSocket.Active := False;

    >

    > server := query2.fieldbyname('login_ip').asstring;

    > if Length(Server) > 0 then

    > begin

    > clientsocket.address := server;

    > clientsocket.Active := true;

    > succ_count := succ_count + 1;

    > end;

    > query2.next;

    > end;

    >

    > 자세한 설명 좀 부탁드립니다. 감사합니다.

    >



    한경아님 구창민입니다~~

    말씀하신 내용에서 ClientSocket은 소켓이 연결되었을 경우

    접속되어 있는 소켓을 끊지 않고서는 다른 곳으로

    접속할수 없습니다.



    그리고, 위의 소스에서 루프내에 소켓접속을 끊고

    다시 다른 곳으로 접속하여 접속을 시도하고 있는데,

    안전하다고 보장할수 없습니다.



    소켓이 접속되면 내부적으로 소켓의 구조체가 가진 특정 패킷을

    송수신 하며, 접속이 성공적으로 된것을 양방에서 확인하는

    과정을 거칩니다.



    그것이 체감으로 느낄수 없을 만큼 빠르기 때문에

    루프내에 넣어서도 돌아가야 할것 같지만,

    서버에서 OnClientConnect 가 발생되며,

    ClientSocket에서 OnConnect가 발생되고, OnWrite가 발생되는데,

    ClinetSocket의 OnWrite는 데이타를 전송해도 될때

    발생되는 이벤트입니다.



    정리하면, ClientSocket의 OnWrite이벤트가 발생하기 전에

    데이타를 송수신 하고 끊고, 다시 다른곳으로 접속하고,

    하는 과정이 루프내에 들어있는 것은 안전을 보장할수

    없다고 말씀 드릴수 있습니다.



    그러므로, 안전한 방법은 접속이 이루어 지고

    ClientSocket의 OnConnect이벤트가 발생될때,

    한경아님이 정의한 패킷구조를 가진(데이타를 던진다 라는..)

    데이타를 전송하는 부분을 기술하면,

    문제가 해결되리라 생각됩니다.



    그리고, 한가지 첨언, 접속을 시도할때 에러처리 루틴을

    삽입하셔야 보다 안전성을 지닌 프로그램이 됩니다.



    그럼.. 즐거운 프로그래밍 되시길~~



  • Profile
    한경아 1999.09.07 20:02
    구창민님 답변 감사합니다. 설명해주신 내용은 이해가 됩니다.

    그런데 아직도 뭐가 잘못되었는지 잘 안되거든요.



    제가 한 방법을 설명드릴께요. 어디서 틀렸는지 말씀해 주시거나 방법을

    가르쳐주시면 감사하겠습니다.



    case1 --- 질문하기 전에 구현한 방법

    버튼을 누르면 for문을 돌면서



    clientsocket.address := ip;

    clientsocket.active := true;

    이렇게 하고



    clientsocket의 onConnect event에

    if clientsocket.Socket.Connected then

    ClientSocket.Socket.SendText(send_message);

    이렇게 했는데 결과는 for문을 다 돌고 마지막의 clientsocket.address값을

    가지고 onConnect event가 발생합니다. 그래서 한대에만 전송이 되구요.



    case2 -----답변을 보고 다음과같이 해 보았습니다.

    clientsocket의 onConnect event에



    for i := 1 to query2.recordcount do

    begin

    if ClientSocket1.Active then

    ClientSocket1.Active := False;



    server := query2.fieldbyname('login_ip').asstring;

    if Length(Server) > 0 then

    begin

    send_message := send_msg.text;

    clientsocket1.address := server;

    clientsocket1.Active := true;

    if clientsocket1.Socket.Connected then

    ClientSocket1.Socket.SendText(send_message);

    end;

    query2.next;

    end;

    이렇게 했는데 clientsocket1.socket.connected가 false로 나와서 전송이

    안되거든요.



    어떻게 해야할까요?? 궂은 날씨임에도 불구하고 즐거운 하루가 되시길...





    > 한경아님 구창민입니다~~

    > 말씀하신 내용에서 ClientSocket은 소켓이 연결되었을 경우

    > 접속되어 있는 소켓을 끊지 않고서는 다른 곳으로

    > 접속할수 없습니다.

    >

    > 그리고, 위의 소스에서 루프내에 소켓접속을 끊고

    > 다시 다른 곳으로 접속하여 접속을 시도하고 있는데,

    > 안전하다고 보장할수 없습니다.

    >

    > 소켓이 접속되면 내부적으로 소켓의 구조체가 가진 특정 패킷을

    > 송수신 하며, 접속이 성공적으로 된것을 양방에서 확인하는

    > 과정을 거칩니다.

    >

    > 그것이 체감으로 느낄수 없을 만큼 빠르기 때문에

    > 루프내에 넣어서도 돌아가야 할것 같지만,

    > 서버에서 OnClientConnect 가 발생되며,

    > ClientSocket에서 OnConnect가 발생되고, OnWrite가 발생되는데,

    > ClinetSocket의 OnWrite는 데이타를 전송해도 될때

    > 발생되는 이벤트입니다.

    >

    > 정리하면, ClientSocket의 OnWrite이벤트가 발생하기 전에

    > 데이타를 송수신 하고 끊고, 다시 다른곳으로 접속하고,

    > 하는 과정이 루프내에 들어있는 것은 안전을 보장할수

    > 없다고 말씀 드릴수 있습니다.

    >

    > 그러므로, 안전한 방법은 접속이 이루어 지고

    > ClientSocket의 OnConnect이벤트가 발생될때,

    > 한경아님이 정의한 패킷구조를 가진(데이타를 던진다 라는..)

    > 데이타를 전송하는 부분을 기술하면,

    > 문제가 해결되리라 생각됩니다.

    >

    > 그리고, 한가지 첨언, 접속을 시도할때 에러처리 루틴을

    > 삽입하셔야 보다 안전성을 지닌 프로그램이 됩니다.

    >

    > 그럼.. 즐거운 프로그래밍 되시길~~

    >