2013-02-23 3 views
0

많은 클라이언트에게 메시지를 보내야하는 응용 프로그램이 있습니다. 클라이언트는 사용자의 컴퓨터에있는 응용 프로그램이며 이러한 응용 프로그램은 때때로 한 번에 여러 날씩 실행됩니다. 서버에 새로운 명령어가 있거나 그렇지 않습니다. 때로는 1 시간, 때로는 하루에 두 가지 새로운 지침 사이에 10 분이있는 경우도 있습니다. 메시지는 고정 된 길이입니다.소켓을 사용하여 클라이언트에게 정기 메시지를 보내는 가장 좋은 방법

이것을 구현하는 가장 좋은 방법은 무엇입니까? 클라이언트가 매 10 초마다 서버를 폴링해야합니까? 새 클라이언트가 연결할 때마다 서버에 새 스레드를 만들어야하며 새 명령이 생길 때까지 연결을 유지 한 다음 클라이언트에 보내 클라이언트가 새 연결을 만들도록해야합니까?

아니면 메시지를 클라이언트에 전달해야합니까? 어떻게하는지 생각하고 있었고, 이것으로 생각해 냈습니다 : 서버와 클라이언트 모두로서 서버 서버. 클라이언트가 핸드 셰이크하면 서버에 주소를 제공합니다. 그런 다음 서버는 클라이언트 (및 다른 클라이언트가 분명히 연결할 수있게하는 서버) 역할을 시작하고 클라이언트와의 연결을 유지합니다. 클라이언트는 서버처럼 행동하고 메시지를 기다립니다.

마지막 하나는 다소 복잡해 보입니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 서버에서 새 메시지 ("지침")는 서버에 "있는"후 최소 15 초 후에 클라이언트에 도착해야합니다.

서버 응용 프로그램은 Windows에서 실행됩니다. 고객의 나는 잘 모르겠지만 멀티 플랫폼이라고 가정합시다. 서버 및 클라이언트 응용 프로그램은 모두 Python으로 작성됩니다.

감사합니다.

+0

아마도 xmpp 프로토콜로 아이디어를 얻을 수 있습니까? (http://en.wikipedia.org/wiki/XMPP) – thebjorn

+0

@thebjorn XMPP는 내가하고있는 일에 약간 과잉이라고 여겨진다. 그러나 나는 인터넷을 통해 의사 소통을하기 위해 그것을 과거에 사용 해왔다. – Taoelism

답변

0

각 클라이언트가 서버에 대한 연결을 연 다음 모든 데이터를 읽을 때까지 기다릴 것입니다. 서버는 게시 할 메시지가있을 때마다 연결된 모든 클라이언트에 기록합니다.

특히 서버는 socket(), bind(), listen()이어야하며 accept() 루프를 입력해야합니다. 새로운 클라이언트가 받아 들여지면, 접속 된 소켓을 액티브 클라이언트의 목록에 추가해야한다. (초기 응용 프로그램 수준의 핸드 쉐이크 나 인증을 제외하고는) 느린 클라이언트가 다른 진행중인 인증이나 심지어 승인 루프를 잠글 수 없도록 별도의 스레드, 분기 된 프로세스 또는 비 차단 이벤트 루프에서 핸드 셰이크 또는 인증을 수행해야합니다.

클라이언트는 다음을 수행해야합니다. 서버에 연결 한 다음 (해당되는 경우 핸드 셰이크 또는 인증을 수행 한 다음) 데이터에 대한 데이터가있을 때까지 기다립니다. 클라이언트가 소켓에서 대기하는 방법은 전통적으로 poll() 또는 select() 중 하나로 수행됩니다. 이러한 호출은 차단 방식으로, 별도의 스레드 또는 프로세스에서 수행 할 수 있습니다. 또는 주 응용 프로그램 루프 또는 반복 타이머에 의해 트리거되는 비 차단 방식으로 수행됩니다.

서버에 게시 할 메시지가있을 때마다 연결된 클라이언트 목록이 반복되어 각 연결된 클라이언트에 대해 write() 개의 메시지를 수행합니다.

클라이언트는 현재 또는 다음 poll() 또는 select()에서 소켓에 읽을 수있는 데이터가 있음을 알리고 메시지를 read()으로 진행합니다.

+0

도움 주셔서 감사합니다.하지만'send()'와'recv()'를 사용하지 않을까요? 'recv()'는 블로킹 호출이기도하며, 메시지의 크기는 고정되어있다. 'recv()'와'write()'대신'read()'와'write()'를 사용하면 어떤 이점이 있습니까? – Taoelism

+0

'send()'와'recv()'는 UDP를 통한 통신에 사용되며, 이는 전달 보증이없는 비 연결형 프로토콜입니다. UDP 패킷은 순서가 잘못되거나 여러 번 도착하거나 전혀 도착하지 않을 수 있습니다. 귀하의 경우에는 클라이언트가 여전히 서버에 연결되어 있는지 여부를 알기를 원한다고 가정 했으므로 가능한 즉시 모든 메시지를받습니다. 이것이 TCP 연결 인'read()'와'write()'에 대한 것입니다. – Tobia

+0

고마워요! 나는 그것을 몰랐다. 나는 소켓에 대해 조금 읽었지만 그것에 대해 읽지는 않았다. Python Sockets HOWTO에는 그것에 대한 언급이 없습니다 (http://docs.python.org/2/howto/sockets.html). 당신이 말하는 것은 정확히 내가 원하는 것입니다 ("클라이언트가 서버에 계속 연결되어 있는지 여부를 알기 때문에 가능한 한 빨리 모든 메시지를받습니다"). – Taoelism

관련 문제