- 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
- 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.
TCP 프로토콜 사용하기
이재홍 http://www.pyrasis.com 2014.12.17 ~ 2015.02.07
클라이언트 작성하기
이제 클라이언트를 작성합니다.
다음은 net 패키지에서 제공하는 TCP 함수입니다.
- func Dial(network, address string) (Conn, error): 프로토콜, IP 주소, 포트 번호를 설정하여 서버에 연결
- func (c *TCPConn) Close() error: TCP 연결을 닫음
- func (c *TCPConn) Read(b []byte) (int, error): 받은 데이터를 읽음
- func (c *TCPConn) Write(b []byte) (int, error): 데이터를 보냄
다음 내용을 GOPATH/src/tcpclient/tcpclient.go 파일로 저장합니다.
package main
import (
"fmt"
"net"
"strconv"
"time"
)
func main() {
client, err := net.Dial("tcp", "127.0.0.1:8000") // TCP 프로토콜, 127.0.0.1:8000 서버에 연결
if err != nil {
fmt.Println(err)
return
}
defer client.Close() // main 함수가 끝나기 직전에 TCP 연결을 닫음
go func(c net.Conn) {
data := make([]byte, 4096) // 4096 크기의 바이트 슬라이스 생성
for {
n, err := c.Read(data) // 서버에서 받은 데이터를 읽음
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(data[:n])) // 데이터 출력
time.Sleep(1 * time.Second)
}
}(client)
go func(c net.Conn) {
i := 0
for {
s := "Hello " + strconv.Itoa(i)
_, err := c.Write([]byte(s)) // 서버로 데이터를 보냄
if err != nil {
fmt.Println(err)
return
}
i++
time.Sleep(1 * time.Second)
}
}(client)
fmt.Scanln()
}
예제를 좀 더 명확하게 하고자 이 클라이언트는 서버에 데이터를 보내는 고루틴과 서버에서 받은 데이터를 출력하는 고루틴 두 부분으로 구성되어 있습니다.
먼저 net.Dial 함수에 tcp와 서버의 IP 주소 및 포트 번호를 설정합니다. 서버에 연결되면 net.Conn이 리턴되고 데이터를 받거나 보낼 수 있습니다. 지연 호출을 사용하여 클라이언트가 끝나면 TCP 연결을 닫아줍니다.
client, err := net.Dial("tcp", "127.0.0.1:8000") // TCP 프로토콜, 127.0.0.1:8000 서버에 연결
if err != nil {
fmt.Println(err)
return
}
defer client.Close() // main 함수가 끝나기 직전에 TCP 연결을 닫음
서버에 데이터를 보내는 고루틴입니다. 마찬가지로 TCP 연결 c에 Write 함수로 서버에 데이터를 보냅니다. 여기서는 1초마다 Hello 문자열에 숫자를 1씩 증가시켜서 보냅니다.
go func(c net.Conn) {
i := 0
for {
s := "Hello " + strconv.Itoa(i)
_, err := c.Write([]byte(s)) // 서버로 데이터를 보냄
if err != nil {
fmt.Println(err)
return
}
i++
time.Sleep(1 * time.Second)
}
}(client)
서버에서 데이터를 받은 뒤 출력하는 고루틴입니다. Read 함수로 서버에서 받은 데이터를 가져옵니다.
go func(c net.Conn) {
data := make([]byte, 4096) // 4096 크기의 바이트 슬라이스 생성
for {
n, err := c.Read(data) // 서버에서 받은 데이터를 읽음
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(data[:n])) // 데이터 출력
time.Sleep(1 * time.Second)
}
}(client)
서버와 클라이언트의 소스 파일을 컴파일한 뒤 실행해봅니다. 먼저 콘솔(터미널)에서 GOPATH/src/tcpserver 디렉터리로 이동한 뒤 서버를 실행합니다(Windows에서는 명령 프롬프트 또는 PowerShell을 실행합니다). 저는 GOPATH를 /home/pyrasis/hello_project로 설정하였습니다.
~$ cd $GOPATH/src/tcpserver
~/hello_project/src/tcpserver$ ./tcpserver
서버를 실행했으면 콘솔에서 GOPATH/src/tcpclient 디렉터리로 이동한 뒤 클라이언트를 실행합니다.
~$ cd $GOPATH/src/tcpclient
~/hello_project/src/tcpclient$ ./tcpclient
Hello 0
Hello 1
Hello 2
Hello 3
... (생략)
클라이언트를 실행하면 Hello 숫자가 1초마다 출력됩니다. 마찬가지로 서버쪽 콘솔에서도 똑같이 출력됩니다.
Hello 0
Hello 1
Hello 2
Hello 3
... (생략)
이처럼 Go 언어에서는 TCP 서버를 간단하게 작성할 수 있습니다. 좀 더 자세한 예제는 'Unit 67 실전 예제: 채팅 서버 작성하기'를 참조하기 바랍니다.
저작권 안내
이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.- 블로그, 게시판 등에 퍼가는 것을 금지합니다.
- 비공개 포스트에 퍼가는 것을 금지합니다.
- 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
- 링크 및 SNS 공유는 허용합니다.