답변:
우선, 무언가가 있고 작동하는 경우 일반적으로 그대로 두는 것이 좋습니다. 왜 깨지지 않은 것을 고쳐야합니까?
그러나 문제가 발생하여 네트워킹 코드를 다시 작성하려면 네 가지 주요 선택이 있다고 생각합니다.
피어-투-피어에서 대규모 멀티 플레이어에 이르는 많은 멀티 플레이어 클라이언트와 서버를 작성 했으므로, 옵션 2는 서버와 게임의 클라이언트 부분 모두에 대해 최소한의 성능으로 매우 복잡하지 않다고 생각합니다. 마지막으로 옵션 4를 사용하지만 일반적으로 전체 프로그램을 다시 생각해야하며 클라이언트가 아닌 서버에 유용합니다.
특히 멀티 스레드 환경에서 소켓을 차단하지 않도록 권고하고 싶습니다. 일반적으로 잠금 및 기타 동기화 기능으로 이어지며 코드의 복잡성을 크게 증가시킬뿐만 아니라 일부 스레드가 대기 할 때 성능이 저하 될 수 있습니다 다른 사람.
그러나 무엇보다도 대부분의 소켓 구현 (및 대부분의 I / O 구현)은 가장 낮은 수준에서 차단되지 않습니다. 사소한 프로그램의 개발을 단순화하기 위해 단순히 차단 작업이 제공됩니다. 소켓이 차단되면 해당 스레드의 CPU가 완전히 유휴 상태이므로 이미 차단되지 않은 작업에 대한 차단 추상화에 대해 차단되지 않은 추상화를 작성하는 이유는 무엇입니까?
비 블로킹 소켓 프로그래밍은 시도하지 않으면 약간 어려워 보이지만 매우 간단하며 이미 입력 폴링을 수행하는 경우 비 블로킹 소켓을 할 마음가짐이 있습니다.
가장 먼저 할 일은 소켓을 비 블로킹으로 설정하는 것입니다. 당신은 그걸로fcntl()
.
그 후, 당신이하기 전에 send()
, recv()
, sendto()
, recvfrom()
, accept()
( connect()
당신은 호출 스레드를 차단할 수 또는 다른 통화 비트 다른입니다) select()
소켓에.select()
소켓을 차단하지 않고 후속 읽기 또는 쓰기 작업을 수행 할 수 있는지 여부를 알려줍니다. 이 경우 원하는 작업을 안전하게 수행 할 수 있으며 소켓이 차단되지 않습니다.
이것을 게임에 포함시키는 것은 매우 간단합니다. 예를 들어 다음과 같이 게임 루프가 이미있는 경우 :
while game_is_running do
poll_input()
update_world()
do_sounds()
draw_world()
end
다음과 같이 변경할 수 있습니다.
while game_is_running do
poll_input()
read_network()
update_world()
do_sounds()
write_network()
draw_world()
end
어디
function read_network()
while select(socket, READ) do
game.net_input.enqueue(recv(socket))
end
end
과
function write_network()
while not game.net_output.empty and select(socket, WRITE) do
send(socket, game.net_output.dequeue())
end
end
리소스 측면에서, 내가 가지고있는 유일한 책이라 할지라도 모든 사람들이 자신의 책장에 있어야한다고 생각하는 유일한 책은 " Unix Network Programming, Vol 1입니다. Richard Stevens의 "입니다. Windows 또는 다른 OS 또는 언어 소켓 프로그래밍을 수행하는 것은 중요하지 않습니다. 이 책을 읽을 때까지 소켓을 이해한다고 생각하지 마십시오.
다중 소켓 프로그래밍 (주로 서버 프로그래밍과 관련) 측면에서 사용 가능한 솔루션에 대한 일반적인 개요를 찾을 수있는 다른 리소스는 이 페이지 입니다.
사용중인 프로그래밍 언어를 쓰지 않았지만 대부분의 언어는 종종 기본 운영 체제의 기능을 활용하는 우수한 비동기 소켓 프레임 워크를 제공합니다.
블로킹 소켓을 기반으로 자체 스레드 구현을 작성할 때 (여러 개의 클라이언트가있는 경우 모든 단일 소켓에 대한 스레드가 필요함) 비동기 소켓 프레임 워크가 이미 제공하는 것을 다시 발명하려고합니다.
따라서 비동기 소켓을 사용하는 것이 좋습니다.
N
클라이언트를 서비스 합니까? 차단하고 있고 나머지 소켓의 상태에 관계없이 각 소켓이 데이터를 처리하도록하려면 소켓 당 하나의 스레드가 있어야합니다. 차단 소켓을 사용하지 마십시오.