개인공부) 서버실습(27) - RecvBuffer

Justin·2022년 6월 19일
0

서버공부

목록 보기
26/45

✅ 지난시간

TCP와 UDP가 뭔지 조금 더 자세하게 알아보고, 이번 프로젝트를 제작해보며 사용하게 될 TCP에 특성에 대해 알아봤다.

TCP의 특성중 현재 처리 가능한 패킷만 받고, 나머지는 나중에 처리하는 것이 있는데 이럴때 상황을 처리하기 위해 코드 작업을 해놓아야 한다.

🚲 Receive Buffer

❗ Recv buffer의 필요성

시작시에 Buffer의 위치를 0으로만 세팅해놓았기 때문에 TCP 특성상 100을 보냈으나, 80만 받는 경우가 생길 때 문제가 발생한다.

만약 80만 받았다면, 80의 위치부터 나머지 20을 다 받은 후에 처리를 해야하기 때문. 그렇기 위해서는 현재 어디까지 받아왔는지를 표기해줄 녀석들이 필요하다.

🔨 제작

🔷 새로운 클래스 생성

byte 타입으로 선언해주어도 되나, 나중에 큰 배열의 일부만 사용할 수 있으니 ArraySegment 타입을 사용한다.

현재 바이트를 어디까지 받아왔고, 얼마나 남았는지 파악하기 위한 변수와 프로퍼티를 제작해준다.

writerPos
받아온 byte의 위치를 표기해줄 변수. 100중 80을 받았다면 80에 위치해 있다.

readerPos
받아온 바이트의 크기에 따라 작업을 처리해주기 위함 100중 80을 받았을 경우는 대기하다가. 100이 모두 채워졌을 때 하나의 처리가 다 채워진 것을 확인하기 위한 변수

DataSize는 사용가능한 유효 데이터의 크기를 체크하기 위한 프로퍼티로 (writerPos - readerPos)를 해주며 그 크기를 측정한다.

FreeSize는 해당 버퍼의 남은 사이즈를 측정하기 위함

🔷 ReadSegment & WriteSegment

현재까지 받은 데이터의 범위가 어디까지인 계산하기위한 Segment, 남은 범위가 어디까지인지 계산하는 Segment로
콘텐츠 단에서 작업 시 필요한 함수

🔷 Clean()

read, write의 pos 값을 계속 이동해주다보면, 나중에 buffer의 크기보다 커지는 경우와 같은 상황이 생길 수 있기에 초기화 시키기 위한 함수가 필요하다.

DataSize. 즉, writePos - readPos 한 값이 0이면 둘다 같은 위치에 있기에 두 값을 모두 0으로 보내면 해결이 되는 경우이다.

두 번째는 Array.Copy()를 사용해서 _buffer 자체를 현재 readPos에 있는 만큼에서 Offset의 위치 까지로 옮겨놓는다.

🔷 OnRead, OnWrite

Read, Write 성공 시 해당 함수들을 호출하여 커서의 위치를 옮기는 역할을 한다.


🌐 Session 작업

start()에서 작업하던 setbuffer는 처리하지 않고, RecvBuffer _recvBuffer = new RecvBuffer(1024); 새로 만든 클래스를 불러와 처음 값을 1024로 동일하게 세팅한다.

작업이 시작 되는 Register 에서 값을 초기화 시켜준 후 writePos부터, 남은 범위 까지의 Segment인 WriteSegment를 가져와 SetBuffer로 설정 해준다.

🔷 OnRecvCompleted 처리

기존에 OnRecv를 통해 arg로 받아온 Segment를 string으로 변환하여 출력하는 작업을 하고 있었다

우선은 write 커서의 이동을 args.BytesTransferred로 간단하게 처리한다(예외를 위한 조건문 추가)

OnRecv에서 작업 시의 buffer.Count 만큼을 뱉어주는 형식으로 수정. ReadSegment로 현재 읽을 수 있는 값 만큼을 넘겨준다.

넘겨준 값을 int 형으로 받은 뒤에 예외 처리를 해주고, 이상이 없다면 넘겨 readPos도 위치를 옮겨주는 처리까지 해주면 끝이다.


profile
인디 게임을 만들며 공부하고 있습니다.

0개의 댓글