Penggunaan net.Conn.Read yang Betul untuk Soket TCP Berterusan
Dalam Go, bekerja dengan soket TCP berterusan melibatkan mewujudkan sambungan dan berterusan membaca data masuk. Fungsi net.Conn.Read bertanggungjawab untuk mendapatkan semula data daripada soket, tetapi tingkah lakunya mungkin tidak jelas serta-merta.
Memahami Pembingkaian Mesej dalam TCP
Tidak seperti sesetengah protokol lain, TCP sememangnya tidak menyediakan pembingkaian mesej. Ini bermakna terpulang kepada aplikasi untuk mentakrifkan kaedah mengasingkan mesej dalam aliran data berterusan.
Pembingkaian Mesej Tradisional dengan Pengepala
Dalam pengalaman C# anda sebelum ini, mesej telah diawali dengan pengepala yang mengandungi saiz mesej. Pendekatan ini membolehkan aplikasi penerima mengetahui panjang tepat mesej berikutnya.
Bagaimana Go Mengendalikan Pengendalian Mesej
Go mengambil pendekatan yang berbeza. Secara lalai, net.Conn.Read() tidak mempunyai mekanisme yang wujud untuk menentukan penghujung mesej. Coretan kod yang anda berikan dalam soalan anda hanya memanggil conn.Read() dalam gelung tanpa mengambil kira sempadan mesej. Ini mungkin berfungsi untuk senario tertentu, tetapi ini bukan penyelesaian yang boleh dipercayai atau berskala.
Penyelesaian: Pembingkaian Mesej Tersuai
Untuk mengendalikan soket TCP berterusan dengan betul, anda perlu melaksanakan pembingkaian mesej tersuai. Ini melibatkan penimbal data masuk dan menghuraikannya mengikut protokol yang anda tentukan sendiri.
Contoh menggunakan bufio.Reader
Satu pendekatan yang disyorkan ialah menggunakan bufio terbina dalam .Pembaca untuk membalut jaring anda.Samb. Pembalut ini menyediakan kefungsian tambahan dan menjadikannya lebih cekap untuk membaca data.
import ( "bufio" "fmt" "io" "net" ) func main() { listener, err := net.Listen("tcp", ":8080") if err != nil { panic(err) } for { conn, err := listener.Accept() if err != nil { continue } go handleConnection(conn) } } func handleConnection(conn net.Conn) { defer conn.Close() r := bufio.NewReader(conn) for { size, err := r.ReadByte() if err != nil { return } buff := make([]byte, size) if _, err := io.ReadFull(r, buff); err != nil { return } fmt.Println("Received:", buff) } }
Dalam contoh ini, fungsi handleConnection mula-mula membaca satu bait daripada sambungan, mewakili panjang mesej berikutnya. Ia kemudian mencipta penimbal dan menggunakan io.ReadFull untuk membaca mesej penuh saiz yang ditentukan itu. Ini membolehkan aplikasi mengendalikan mesej dengan panjang yang berbeza-beza dengan lancar.
Atas ialah kandungan terperinci Bagaimana Mengendalikan Pembingkaian Mesej dengan Amanah dengan net.Conn.Read dalam Go for Persistent TCP Sockets?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!