내 서버에서 DisconnectEx 와 함께 CreateIOCompletionport 를 쓰는 일반적인 코드에서

 

접속을 종료할 때 DisconnectEx로 걸어준 뒤 다음 재접속 할때 CreateIoCompletionPort 를 한번 더 걸어줄시 

 

에러 오류가 나오는 것을 확인 했다.

 

이미 걸려있는 소켓에 대해 한번 더 걸어줄시  나타나는 현상으로 보인다.

 

TF_REUSE_SOCKET 의 인자를 사용하면서 SOCKET을 재사용하게 되면 이러한 점을 참고해서 해야겠다고 생각한다.

 

ps. DisconnectEx를 해당 소켓에 걸어준다고 바로 해제되는 것이 아니라, 클라이언트 쪽에서 closesocket을 불러야만

 

이 함수가 작동한다.  setsockopt 에서 TF_REUSE_SOCKET 을 쓰는 것에 비해 장점은 서버쪽에서 클라이언트 소켓을

 

강제 종료함으로써 생기는 오류의 최소화가 아닐까 생각한다.

내가 만든 게임서버들의 패킷송수신량을 파이썬의 plotly라는 라이브러리를 통해 시각화하기 위해서 간단하게 클라이언트와 서버간 통신을 할 수 있는 프로그램이 필요했다.

 

서버는 스레드를 이용해 계속적으로 recv를 받는 형태, 클라이언트는 send를 통해 계속 보내는 형태로 구성하였다.

 

 

서버 코드

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

from socket import *

import threading

 

clientSockets = [];

clientAddressList = [];

serverSock = socket(AF_INET, SOCK_STREAM);

serverSock.bind(('',9000));

serverSock.listen(5);

 

shutdown = False;

 

def recvData(connectionSocket, clientAddr):

while(True):

data = connectionSocket.recv(1024);

print(str(clientAddr) + " : " , data.decode("utf-8") );

 

 

 

def StartNetwork():

while(shutdown == False):

connectionSocket, clientAddr = serverSock.accept();

clientSockets.append(connectionSocket);

clientAddressList.append(clientAddr);

print(str(clientAddr) + " requested Connection!! " );

threading.Thread(target = recvData, args=(connectionSocket,clientAddr)).start();

 

 

StartNetwork();

 

Colored by Color Scripter

 

클라 코드

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

from socket import *

import threading

 

clientSockets = [];

clientAddressList = [];

serverSock = socket(AF_INET, SOCK_STREAM);

serverSock.bind(('',9000));

serverSock.listen(5);

 

shutdown = False;

 

def recvData(connectionSocket, clientAddr):

while(True):

data = connectionSocket.recv(1024);

print(str(clientAddr) + " : " , data.decode("utf-8") );

 

 

 

def StartNetwork():

while(shutdown == False):

connectionSocket, clientAddr = serverSock.accept();

clientSockets.append(connectionSocket);

clientAddressList.append(clientAddr);

print(str(clientAddr) + " requested Connection!! " );

threading.Thread(target = recvData, args=(connectionSocket,clientAddr)).start();

 

 

StartNetwork();

 

Colored by Color Scripter

서버1에 1, 2, 3 


서버2에 4, 5, 6을 가지고 있고.


서버1의 로드한계를 1000,


서버2의 로드한계를 10000으로 설정,


룸 1, 2, 3에 100명의 인원을 고르게 분산하여 할당,


룸 하나당 5000~6000사이의 패킷송수신량이 발생함


즉, 서버1은 패킷송수신량이 조금이라도 있다면 룸을 서버2에 넘겨주고


서버2에서는 자신이 소유한 룸의 갯수가 2개이상이 됀다면 서버1에게 룸을 전달함.


(예외처리가 좀더 필요한 상태.)


과정 1) 더미클라이언트 100대를 서버 1에 룸1:33, 룸2:34 룸3:33 으로 분산함.


과정 2) 서버1에서 로드가 발생하여 패킷송수신량이 가장 많은 룸2를 서버2에 할당함


과정 3) 서버1에서 로드가 발생하여 패킷송수신량이 가장 많은 룸1을 서버2에 할당함.


과정 4, 5) 서버 1에서 로드가 발생하여 패킷송수신량이 가장 많은 룸3을 서버2에 할당함, 


서버2에서 로드가 발생하여 패킷송수신량이 가장 많은 룸2를 서버1에 할당함.


최종 : 서버1 : 2    서버2 : 1,3 을 소유하게 됌. 



+ Recent posts