Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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 30
Archives
Today
Total
관리 메뉴

Code Habit

go ) TCP echo 서버/클라이언트 size 문제 본문

카테고리 없음

go ) TCP echo 서버/클라이언트 size 문제

코드베어 2020. 9. 1. 23:49

앞에서 go를 이용한 TCP ehco 서버/클라이언트를 만들어 보았는데, 구현에 문제점이 있다고 지적하였었다. TCP 통신은 원래 데이터간의 경계가 존재 하지 않는다. 즉 네트워크나 PC 상황에 따라 데이터 전송이 밀려 자칫 데이터 전송이 의도치 않게 될수 있다는 것이다. 

 

그래서 이를 보완하기 위해 본 데이터를 전송하기 전에 미리 전송되는 데이터의 size를 알려줘 데이터 전송에 오차가 없도록 할 수 있다. 참 다행히도 TCP 통신은 데이터의 무결성을 보장하기 때문에 전송하는 데이터가 중간에 유실될 염려는 하지 않아도 된다. 

 

다음은 예제 코드이다.

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
30
func ConnHandler(conn net.Conn) {
    sizeBuf := make([]byte4)
    var bodyBuf []byte
 
    for {
        // get size
        n, err := conn.Read(sizeBuf)
        if nil != err {
            if io.EOF == err {
                log.Println("err(eof):", err)
                break
            }
            log.Println("err:", err)
            break
        }
        size := binary.BigEndian.Uint32(sizeBuf)
 
        // get body
        recvBuf := make([]bytesize)
        readsize := size
        for readsize > 0 {
            n, err = conn.Read(recvBuf)
 
            if n > 0 {
                bodyBuf = append(bodyBuf, recvBuf...)
                readsize -= uint32(n)
            }
        }
    }
}

먼저 size를 받고 그 크기만큼 본 데이터를 받는데 혹시 데이터를 한번에 다 받아오지 못할 수도 있으니 for문 안에서 size 만큼 받아내는 예제이다. 16줄에서 []byte형 데이터를 정수형 데이터(uint32)로 변환하기 위해 "encoding/binary" 패키지 안의 함수를 사용하였으며 순차로 받은 버퍼들을 25줄에서 append함수로 합쳐 주었다. 데이터를 다 읽어 readsize가 0이 되면 for문을  빠져나온다.