
ãšããæ¹ãž ãããã¯ãŒã¯ãšãããã³ã«ã®çè§£ã«å°å¿µããŸãã
ç°¡åã«
ãã®èšäºã§ã¯ãä¿¡é Œæ§ã®é«ãããŒã¿éä¿¡ã®åºæ¬ã«ã€ããŠèª¬æããäŸãå®è£ ããŸãã ãUDP ãš TCP ãå«ããã«åºã¥ã , , ãã以å€ã®å Žåã¯ã誰ããã¿ãã³ããŠã ãšãªãªãã§ããã«ã€ããŠã®ã¿è°è«ããŠããŸãã
ãã©ã³ã¹ããŒãå±€ãããã³ã«
ç°ãªããã¹ãäžã§å®è¡ãããŠããã¢ããªã±ãŒã·ã§ã³ ããã»ã¹éã«è«çæ¥ç¶ãæäŸããŸããã¢ããªã±ãŒã·ã§ã³ã®èгç¹ããèŠããšãè«çæ¥ç¶ã¯ããã»ã¹ãçŽæ¥æ¥ç¶ãããã£ãã«ã®ããã«èŠããŸãã

ãšã³ã ã·ã¹ãã ã§ã¯ãµããŒããããŠããŸããããããã¯ãŒã¯ ã«ãŒã¿ãŒã§ã¯ãµããŒããããŠããŸãã (- ãé€ã) ïŒãéä¿¡åŽã§ã¯ããã©ã³ã¹ããŒãå±€ã¯ãéä¿¡ã¢ããªã±ãŒã·ã§ã³ ããã»ã¹ããåãåã£ãã¢ããªã±ãŒã·ã§ã³å±€ããŒã¿ããã»ã°ã¡ã³ããšåŒã°ãããã©ã³ã¹ããŒãå±€ãã±ããã«å€æããŸãã

ããã¯ãã¢ããªã±ãŒã·ã§ã³å±€ã¡ãã»ãŒãžã (å¿ èŠã«å¿ããŠ) ãã©ã°ã¡ã³ãã«åå²ããããããã«ãã©ã³ã¹ããŒãå±€ããããŒã远å ããããšã«ãã£ãŠè¡ãããŸãã

次ã«ããã©ã³ã¹ããŒãå±€ã¯ã»ã°ã¡ã³ããéä¿¡è ã®ãããã¯ãŒã¯å±€ã«æž¡ããããã§ã»ã°ã¡ã³ãã¯ãããã¯ãŒã¯å±€ãã±ãã (ããŒã¿ã°ã©ã ) ã«ã«ãã»ã«åãããŠéä¿¡ãããŸããåä¿¡åŽã§ã¯ããããã¯ãŒã¯å±€ãããŒã¿ã°ã©ã ãããã©ã³ã¹ããŒãå±€ã»ã°ã¡ã³ããæœåºããããããã©ã³ã¹ããŒãå±€ã«æž¡ããŸããæ¬¡ã«ããã©ã³ã¹ããŒãå±€ã¯åä¿¡ããã»ã°ã¡ã³ããåŠçããŠããã®ããŒã¿ãåä¿¡ã¢ããªã±ãŒã·ã§ã³ãå©çšã§ããããã«ããŸãã

ä¿¡é Œæ§ã®é«ãããŒã¿éä¿¡ã®åå
å®å šã«å®å šãªãã£ãã«ãä»ããä¿¡é Œæ§ã®é«ãããŒã¿éä¿¡
æãåçŽãªã±ãŒã¹ãéä¿¡åŽã¯äžäœå±€ããããŒã¿ãåãåãããããå«ããã±ãããäœæããŠãã£ãã«ã«éä¿¡ããã ãã§ãã
СеÑвеÑ
package main
import (
"log"
"net"
)
func main() {
// IP-аЎÑÐµÑ ÑеÑвеÑа О пПÑÑ
serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
if err != nil {
log.Fatal(err)
}
// ÑПзЎаеЌ ÑÐŸÐºÐµÑ Ñ Ð¿ÐŸÑÑПЌ
serverConn, err := net.ListenUDP("udp", serverAddr)
if err != nil {
log.Fatal(err)
}
// ПÑлПжеММПе закÑÑÑОе ÑПеЎОМеМОÑ
defer serverConn.Close()
// ÑПзЎаеЌ бÑÑÐµÑ ÐŽÐ»Ñ ÐŽÐ°ÐœÐœÑÑ
buf := make([]byte, 1024)
// жЎеЌ ÑПеЎОМеМОе
for {
// ÑОÑаеЌ запÑПÑ
n, addr, err := serverConn.ReadFromUDP(buf)
// пеÑеЎаеЌ ЎаММÑе в ÐÐРХÐÐÐ ÑÑПвеМÑ: в МаÑеЌ ÑлÑÑае stdout
println(string(buf[0:n]), " form ", addr.IP.String())
if err != nil {
log.Fatal(err)
}
// ПÑвеÑа МеÑ, Ñ.к. ÑÑП UDP + МаЎежМÑй каМал
}
}ã¯ã©ã€ã¢ã³ã
package main
import (
"fmt"
"log"
"net"
"time"
)
func main() {
// IP-аЎÑÐµÑ ÑеÑвеÑа О пПÑÑ
serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
if err != nil {
log.Fatal(err)
}
// лПкалÑМÑй IP-аЎÑÐµÑ Ðž пПÑÑ
localAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
if err != nil {
log.Fatal(err)
}
// ÑÑÑаМПвка ÑПеЎОМеМОÑ
conn, err := net.DialUDP("udp", localAddr, serverAddr)
if err != nil {
log.Fatal(err)
}
// ПÑлПжеММПе закÑÑÑОе ÑПеЎОМеМОÑ
defer conn.Close()
for {
// пПлÑÑеМОе ЎаММÑÑ
ÐŸÑ ÐÐРХÐÐÐÐ ÑÑПвМÑ
fmt.Print("ÐвеЎОÑе ÑÑÑПÑМПе пÑеЎлПжеМОе > ")
var msg string
_, err := fmt.Scanf("%s", &msg)
if err != nil {
log.Fatal(err)
}
// пеÑеЎаеÑÑÑ Ð¿ÐŸÑПк байÑ, а Ме ÑÑÑПка
buf := []byte(msg)
// запОÑÑ (пеÑеЎаÑа) в ÑПеЎОМеМОе
_, err = conn.Write(buf)
if err != nil {
log.Fatal(err)
}
// 1 ÑекÑМЎПÑкÑ
time.Sleep(time.Second * 1)
}
}ãšã©ãŒãçºçããå¯èœæ§ã®ãããã£ãã«äžã§ã®ä¿¡é Œæ§ã®é«ãããŒã¿éä¿¡
次ã®ã¹ãããã§ã¯ãéä¿¡ããããã¹ãŠã®ãã±ãããéä¿¡ãããé åºã§åä¿¡ããããšä»®å®ããŸããããã£ãã«ãæã æªã¿ã®ããããŒã¿ãéä¿¡ããããããã±ããå ã®ããããç ŽæããŠããå¯èœæ§ããããŸãã

ãã®å Žåãæ¬¡ã®ã¡ã«ããºã ã䜿çšãããŸãã
- ãšã©ãŒæ€åºã
- ãã£ãŒãããã¯;
- åéä¿¡ã
éä¿¡ãè€æ°åç¹°ãè¿ãããã®åæ§ã®ã¡ã«ããºã ãåããä¿¡é Œæ§ã®é«ãããŒã¿è»¢éãããã³ã«ã¯ãèªååéèŠæ± (ARQ) ãããã³ã«ãšåŒã°ããŸãã
ããã«ãåä¿¡åŽãæåŸã®ãã±ããã®è»¢éçµæã«é¢ããæ
å ±ããŸã£ããåãåããªãå Žåãåä¿¡ãšã©ãŒãçºçããå¯èœæ§ãèæ
®ãã䟡å€ããããŸãã
ãã®åé¡ã®è§£æ±ºçã¯ãTCP ã§ã䜿çšãããŠããããã±ããã®ã·ãŒã±ã³ã¹çªå·ãå«ãæ°ãããã£ãŒã«ããããŒã¿ ãã±ããã«è¿œå ããããšã§ãã

ãã±ããã®æªã¿ãæå€±ãçºçããä¿¡é Œæ§ã®äœããã£ãã«äžã§ã®ä¿¡é Œæ§ã®é«ãããŒã¿éä¿¡
æ®å¿µãªãããæªã¿ã«å ããŠããããã¯ãŒã¯å
ã§ãã±ããæå€±ãçºçããŸãã
ãã®åé¡ã解決ããã«ã¯ã次ã®ã¡ã«ããºã ãå¿
èŠã§ãã
- ãã±ããæå€±ã®äºå®ã倿ããã
- 倱ããããã±ãããåä¿¡è ã«åé ä¿¡ããŸãã
ããã«ãè·ç©ã®çŽå€±ã«å ããŠãé åæžã®çŽå€±ããŸãã¯äœãçŽå€±ããŠããªãå Žåã§ãé éãå€§å¹ ã«é ããå¯èœæ§ã«ãåããå¿ èŠããããŸãããã¹ãŠã®å Žåã«ãããŠãåãããšãè¡ããããã±ãããåéä¿¡ãããŸããæéãå¶åŸ¡ããããã«ããã®ã¡ã«ããºã ã§ã¯ã«ãŠã³ãããŠã³ ã¿ã€ããŒã䜿çšããŸããããã«ãããåŸ æ©ééã®çµäºã決å®ã§ããŸããããã§ããã±ãŒãžã«ã¯ TCPKeepAlive ã¯ããã©ã«ãã§ 15 ç§ã«èšå®ãããŠããŸãã
// defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
// See golang.org/issue/31510
const (
defaultTCPKeepAlive = 15 * time.Second
)éä¿¡åŽã¯ããã±ãããéä¿¡ããããã³ã« (1 åç®ãš 2 åç®ã®äž¡æ¹ã§) ã¿ã€ããŒãéå§ããã¿ã€ããŒããã®å²ã蟌ã¿ãåŠçããã¿ã€ããŒã忢ããå¿ èŠããããŸãã
ããã§ãä¿¡é Œæ§ã®é«ãããŒã¿è»¢éãããã³ã«ã®éèŠãªæŠå¿µãçè§£ã§ããŸããã
- ãã§ãã¯ãµã ã
- ããã±ãŒãžã®ã·ãŒã±ã³ã¹çªå·ã
- ã¿ã€ããŒ;
- ããžãã£ããªã¬ã·ãŒããšãã¬ãã£ããªã¬ã·ãŒãã
ãããããã ãã§ã¯ãããŸããïŒ
ãã€ãã©ã€ã³ã«ããä¿¡é Œæ§ã®é«ãããŒã¿è»¢éãããã³ã«
ãã§ã«æ€èšããããªã¢ã³ãã§ã¯ãä¿¡é Œæ§ã®é«ãé ä¿¡ãããã³ã«ã¯éåžžã«éå¹ççã§ãã RTT ãå¢å ããã«ã€ããŠãéä¿¡ãã£ãã«ã«ãã£ãŠæäŸãããéä¿¡ããé ãããªãå§ããŸããå¹çãé«ããéä¿¡ãã£ãã«å®¹éãããæå¹æŽ»çšããããã«ããã€ãã©ã€ã³åŠçã䜿çšãããŸãã

ãã€ãã©ã€ã³ã䜿çšãããšã次ã®ãããªçµæãåŸãããŸãã
- éä¿¡ããããã¹ãŠã®ãã±ãã (åéä¿¡ãé€ã) ãäžæã«èå¥ããå¿ èŠããããããã·ãŒã±ã³ã¹çªå·ã®ç¯å²ãæ¡å€§ããŸãã
- éä¿¡åŽãšåä¿¡åŽã®ãããã¡ãå¢ããå¿ èŠãããã
ã·ãŒã±ã³ã¹çªå·ã®ç¯å²ãšãããã¡ ãµã€ãºã®èŠä»¶ã¯ããã±ããã®ç Žæãæå€±ãé å»¶ã«å¿ããŠãããã³ã«ãå®è¡ããã¢ã¯ã·ã§ã³ã«ãã£ãŠç°ãªããŸãããã€ãã©ã€ã³ã®å Žåããšã©ãŒãä¿®æ£ããã«ã¯ 2 ã€ã®æ¹æ³ããããŸãã
- N åã®ãã±ãããè¿ããŸãã
- éžæçãªç¹°ãè¿ãã
N ãã±ãããé¡ã - ã¹ã©ã€ãã£ã³ã° ãŠã£ã³ã㊠ãããã³ã«

éä¿¡è ã¯æ¬¡ã® 3 çš®é¡ã®ã€ãã³ãããµããŒãããå¿ èŠããããŸãã
- äžäœã¬ãã«ã®ãããã³ã«ã«ããåŒã³åºããããŒã¿éä¿¡é¢æ°ããäžãããåŒã³åºããããšãéä¿¡åŽã¯ãŸããŠã£ã³ããŠã®åãŸãå ·åïŒã€ãŸããåä¿¡ã®åä¿¡ãåŸ ã£ãŠãã N åã®éä¿¡ã¡ãã»ãŒãžã®ååšïŒããã§ãã¯ããŸãããŠã£ã³ããŠã空ã®å Žåãæ°ãããã±ãããçæãããŠéä¿¡ããã倿°å€ãæŽæ°ãããŸãããã以å€ã®å Žåãéä¿¡åŽã¯äžäœå±€ã«ããŒã¿ãè¿ããŸããããã¯ããŠã£ã³ããŠããã£ã±ãã§ããããšãæé»çã«ç€ºããŸããéåžžãäžäœå±€ã¯ãã°ããããŠããå床ããŒã¿ã®éä¿¡ã詊ã¿ãŸããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãéä¿¡åŽã¯ããŒã¿ã (ããã«éä¿¡ããã®ã§ã¯ãªã) ãããã¡ãªã³ã°ãããããŠã£ã³ããŠã空ã®å Žåã«ã®ã¿äžäœå±€ãéä¿¡é¢æ°ãåŒã³åºããããã«ããåæã¡ã«ããºã (ã»ããã©ããã©ã°ãªã©) ãåããŠããå¯èœæ§ããããŸãã ã
- 確èªãåãåããŸãããã®ãããã³ã«ã§ã¯ãã·ãŒã±ã³ã¹çªå· N ã®ãã±ããã«ã€ããŠãN ããåã®ã·ãŒã±ã³ã¹çªå·ãæã€ãã¹ãŠã®ãã±ãããæ£åžžã«åä¿¡ãããããšã瀺ãäžè¬ç¢ºèªå¿çãçºè¡ãããŸãã
- åŸ æ©æéãçµäºããŸããããã±ãããšåä¿¡ã®æå€±ãšé å»¶ã®äºå®ã倿ããããã«ããããã³ã«ã¯ã¿ã€ããŒã䜿çšããŸããã¿ã€ã ã¢ãŠãééãçµéãããšãéä¿¡åŽã¯éä¿¡æžã¿ã®æªç¢ºèªãã±ããããã¹ãŠåéä¿¡ããŸãã
éžæçç¹°ãè¿ã
ãŠã£ã³ã㊠ãµã€ãºãšã¹ã«ãŒããããšäŒæé å»¶ã®ç©ã倧ããå Žåã倿°ã®ãã±ããããã€ãã©ã€ã³å ã«ååšããå¯èœæ§ããããŸãããã®ãããªå Žåãåäžã®ãã±ãã ãšã©ãŒã«ããããã®ã»ãšãã©ãäžèŠãªå€§éã®ãã±ãããåéä¿¡ãããå¯èœæ§ããããŸãã
äŸ
ããã ãã©ã¯ãã£ã¹ã¯å®éã®å®è£ ã§åéãããŸã ããããŠã誰ãããã®æ¹æ³ãæãããç¥ã£ãŠãããšããã - .
СеÑвеÑ
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
)
func main() {
// ÑПзЎаеЌ ÑÐŸÐºÐµÑ Ñ Ð¿ÐŸÑÑПЌ
ln, err := net.Listen("tcp", ":8081")
if err != nil {
log.Fatalln(err)
}
// ПжОЎаМОе вÑзПва
conn, _ := ln.Accept()
for {
// ÑÑОÑÑваМОе ЎаММÑÑ
msg, err := bufio.NewReader(conn).ReadString('n')
if err != nil {
log.Fatalln(err)
}
// вÑвПЎ ÑППбÑÐµÐœÐžÑ Ð² stdout
fmt.Print("Message Received:", string(msg))
// пеÑевПЎ ÑÑÑПкО в веÑÑ
МОй ÑегОÑÑÑ
newMsg := strings.ToUpper(msg)
// ПÑпÑавка ЎаММÑÑ
conn.Write([]byte(newMsg + "n"))
}
}ã¯ã©ã€ã¢ã³ã
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func main() {
// ÑÑÑаМПвка ÑПеЎОМеМОÑ
conn, err := net.Dial("tcp", "127.0.0.1:8081")
if err != nil {
log.Fatalln(err)
}
for {
// ÑÑОÑÑваМОе ЎаММÑÑ
Ñ stdin
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to send: ")
// пПÑÑÑПÑМП
text, err := reader.ReadString('n')
if err != nil {
log.Fatalln(err)
}
// ПÑпÑавка
fmt.Fprintf(conn, text+"n")
// пÑОеЌ
msg, err := bufio.NewReader(conn).ReadString('n')
if err != nil {
log.Fatalln(err)
}
// вÑвПЎ пПлÑÑеММПгП ПÑвеÑа
fmt.Print("Msg from Server: " + msg)
}
}åºå
ä¿¡é Œæ§ã®é«ãããŒã¿è»¢éãšäœ¿çšãä¿èšŒããã¡ã«ããºã
ÐеÑ
аМОзЌ
ç³ã蟌ã¿ã»ã³ã¡ã³ã
ãã§ãã¯ãµã
éä¿¡ãã±ããå
ã®ããããšã©ãŒãæ€åºããããã«äœ¿çšãããŸã
ã¿ã€ããŒ
ã¿ã€ã ã¢ãŠãééãã«ãŠã³ãããŠã³ããæéåãã«ãªã£ãããšã瀺ããŸããåŸè
ã¯ãé«ã確çã§ãã±ãããŸãã¯ãã®åä¿¡ãéä¿¡äžã«å€±ãããããšãæå³ããŸãããã±ãããé
å»¶ããŠé
ä¿¡ããããã®ã®ã倱ãããŠããªãå ŽåïŒã¿ã€ã ã¢ãŠãééã®æ©ææéåãïŒããŸãã¯åä¿¡ã倱ãããå Žåãåéä¿¡ã«ããåä¿¡åŽã§ãã±ãããéè€ããŸãã
ã·ãªã¢ã«ãã³ããŒ
éä¿¡è
ããåä¿¡è
ã«éä¿¡ãããããŒã¿ ãã±ããã®é£ç¶çªå·ä»ãã«äœ¿çšãããŸããåä¿¡ãã±ããã®ã·ãŒã±ã³ã¹çªå·ã®ã®ã£ããã«ãããåä¿¡åŽã¯ãã±ããæå€±ãæ€åºã§ããŸããåããã±ãã ã·ãŒã±ã³ã¹çªå·ã¯ããã±ãããäºãã«éè€ããŠããããšãæå³ããŸãã
確èª
åä¿¡åŽã«ãã£ãŠçæããã察å¿ãããã±ãããŸãã¯ãã±ããã®ã°ã«ãŒããæ£åžžã«åä¿¡ãããããšãéä¿¡åŽã«ç€ºããŸããéåžžã確èªå¿çã«ã¯ãæ£åžžã«åä¿¡ããããã±ããã®ã·ãŒã±ã³ã¹çªå·ãå«ãŸããŸãããããã³ã«ã«å¿ããŠãå人ãšã°ã«ãŒãã®ç¢ºèªãåºå¥ãããŸã
é°æ§ç¢ºèª
ãã±ãããæ£ããåä¿¡ãããªãã£ãããšãåä¿¡è
ãéä¿¡è
ã«éç¥ããããã«äœ¿çšãããŸããåŠå®å¿çã«ã¯éåžžãæ£ããåä¿¡ãããªãã£ããã±ããã®ã·ãŒã±ã³ã¹çªå·ãå«ãŸããŸãã
çªãã³ã³ãã¢å
ãã±ããã®éä¿¡ã«äœ¿çšã§ããã·ãŒã±ã³ã¹çªå·ã®ç¯å²ãå¶éããŸãããã«ããã£ã¹ããšãã³ãã·ã§ã€ã¯ã¯ã確èªå¿çãåŸ
ã€å Žåãšæ¯èŒããŠããããã³ã«ã®ã¹ã«ãŒãããã倧å¹
ã«åäžãããããšãã§ããŸãããããã説æããããã«ããŠã£ã³ã㊠ãµã€ãºã¯ãåä¿¡åŽã®åä¿¡èœåãšãããã¡ãªã³ã°èœåãããã³ãããã¯ãŒã¯è² è·ã¬ãã«ã«åºã¥ããŠèšç®ã§ããŸãã
ãããã¯ãŒãã³ã°ã« Go ã䜿çšãããã®ä»ã®äŸ
Ð .
åºæïŒ habr.com
