2012-10-12 2 views
0

나는 간단한 멀티 플레이어 온라인 텍스트 게임을하고 있는데, select()poll()은 I/O 멀티플렉싱에 널리 사용되는 방법이라고 읽었습니다.C의 간단한 실시간 게임 서버에 대한 select()/poll() 메소드가 있습니까?

select입니다. 나는 그것을 실행하고 다음과 같이 3 파이썬 테스트 클라이언트를 만든 :

import socket 
import time 

port = 5555 
test = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
test.connect(('localhost', port)) 

while 1: 
    test.send('aaaa') 
    time.sleep(0.5) 

가 그럼 난 다른 문자열 ( aaaa, 55..)와 (서버를 실행중인 동일한 컴퓨터에서) 클라이언트를 실행했습니다.

서버의 출력은

Server: got message: `aaaa' 
Server: got message: `55aa' 
Server: got message: `aaaa' 
Server: got message: `55aa' 
Server: got message: `..aa' 

문자열이 혼합지고 있었다이었다.

이것은 바보 같은 컴파일 오류, 내 테스트 클라이언트의 오류 또는 동일한 컴퓨터에서 클라이언트와 서버를 실행한다는 사실입니까? 또는이 프로그램에서이 용도로 select을 사용하지 않아야한다고 말하고 있습니까? 멀티 플레이어 게임 서버 (아마도 초당 많은 메시지를 얻는다)에 이것을 사용할 것이므로 메시지가 섞일 수 있다고 생각하지 않습니다.

답변

1

클라이언트와 서버는 완전히 비동기입니다. CPU에서 어떤 순서로 시간을 가질 지 모릅니다. 또한 네트워크는 전달 순서에 대해 어떠한 보장도하지 않습니다 (TCP는 응용 프로그램이 단일 클라이언트 을 보낸 순서대로의 데이터를 보도록합니다).

선택/폴링 읽을 데이터가있는 소켓 목록을 반환합니다. select/poll을 다시 호출하기 전에 모두 읽어야합니다. 그렇지 않으면 낮은 번호의 포트에서 연결의 우선 순위를 지정하게됩니다.

읽기는 원시 데이터이며 어떠한 방식으로도 종료되지 않으므로 보낸 사람이 소켓에 쓰기에 NUL 종결자가 포함되어 있지 않으면 문자열로 직접 덤프 할 수 없습니다.

+0

패키지가 잘못 도착 했어도 괜찮습니다. 문제는, 그것들이 혼합되어지고 있다는 것입니다. 두 개의 메시지가 섞여서 게임 명령으로 게임 서버에 메시지를 보내고 있다면 "왼쪽으로 5 개를 찍는 것"또는 "한 상자를 먹는 것"과 같은 무언가를 할 수 있습니다. – user1002327

+2

다른 클라이언트의 데이터가 OS에서 섞이지 않습니다. 각 포트는 다른 모든 포트와 완전히 독립적입니다. 나는 당신이보고있는 것이 당신의 ** 버퍼가 읽기 사이에 제거되지 않는다고 의심합니다 **. 그것은 4자를 가지고 처음 2 바이트로 2를 읽었지만, 다음 2는 이전의 읽기에서 있었던 것처럼 남아 있습니다. 소켓 읽기는 raw 바이트를 반환합니다. 읽지 않는 NUL이 읽기에 추가되지 않으며'send()'호출도 전송하지 않습니다. –

+0

예제에 사용 된 버퍼가 명시 적으로 할당되지 않았습니다. 'read_from_client' 함수의 지역 변수입니다. 나는 심지어 같은 함수의 맨 끝에서 bzero (버퍼, sizeof (버퍼))를 추가하는 버퍼를 지우지 만 문자열은 여전히 ​​섞여있다. 그래도 마지막 부분에 대해서는 완전히 옳다. 나는'send' 명령의 끝에'\ 0'을 추가했고 이제는 작동합니다. 동의 할 수 있도록 * 답을 편집하십시오. | 신경 쓰지 마라, 네가 다른 사람이라고 생각 했어. 나는 당신의 대답을 받아 들일 것입니다, 고마워요. – user1002327