英文:
How do you use the net functions effectively in Go?
问题
例如,具有基本数据包协议,如:
[packetType int][packetId int][data []byte]
并使用它创建一个客户端和服务器来执行简单的操作(例如聊天)。
英文:
For example, having basic packet protocol, like:
[packetType int][packetId int][data []byte]
And making a client and server doing simple things with it (egx, chatting.)
答案1
得分: 5
这是一个具有松散的恐慌错误处理的客户端和服务器。它们有一些限制:
- 服务器一次只能处理一个客户端连接。您可以通过使用goroutines来修复这个问题。
- 数据包始终包含100字节的有效负载。您可以通过在数据包中放置一个长度并且不使用encoding/binary来修复这个问题,但我保持了简单。
这是服务器的代码:
package main
import (
"encoding/binary"
"fmt"
"net"
)
type packet struct {
// 字段名称必须大写以进行编码/二进制处理。
// 使用明确大小的类型非常重要。
// 使用int32而不是int等。
Type int32
Id int32
// 这必须是数组而不是切片。
Data [100]byte
}
func main() {
// 在端口2000上设置一个监听器
l, err := net.Listen("tcp", ":2000")
if err != nil {
panic(err.String())
}
for {
// 开始监听连接
conn, err := l.Accept()
if err != nil {
panic(err.String())
}
handleClient(conn)
}
}
func handleClient(conn net.Conn) {
defer conn.Close()
// 一个客户端已连接;现在等待一个数据包
var msg packet
binary.Read(conn, binary.BigEndian, &msg)
fmt.Printf("接收到一个数据包:%s\n", msg.Data)
// 发送响应
response := packet{Type: 1, Id: 1}
copy(response.Data[:], "Hello, client")
binary.Write(conn, binary.BigEndian, &response)
}
这是客户端。它发送一个类型为0、id为0、内容为“Hello, server”的数据包。然后它等待响应,打印它并退出。
package main
import (
"encoding/binary"
"fmt"
"net"
)
type packet struct {
Type int32
Id int32
Data [100]byte
}
func main() {
// 连接到本地主机的端口2000
conn, err := net.Dial("tcp", ":2000")
if err != nil {
panic(err.String())
}
defer conn.Close()
// 发送一个数据包
msg := packet{}
copy(msg.Data[:], "Hello, server")
err = binary.Write(conn, binary.BigEndian, &msg)
if err != nil {
panic(err.String())
}
// 接收响应
var response packet
err = binary.Read(conn, binary.BigEndian, &response)
if err != nil {
panic(err.String())
}
fmt.Printf("响应:%s\n", response.Data)
}
英文:
Here's a client and server with sloppy panic error-handling. They have some limitations:
- The server only handles one client connection at a time. You could fix this by using goroutines.
- Packets always contain 100-byte payloads. You could fix this by putting a length in the packet somewhere and not using encoding/binary for the entire struct, but I've kept it simple.
Here's the server:
package main
import (
"encoding/binary"
"fmt"
"net"
)
type packet struct {
// Field names must be capitalized for encoding/binary.
// It's also important to use explicitly sized types.
// int32 rather than int, etc.
Type int32
Id int32
// This must be an array rather than a slice.
Data [100]byte
}
func main() {
// set up a listener on port 2000
l, err := net.Listen("tcp", ":2000")
if err != nil {
panic(err.String())
}
for {
// start listening for a connection
conn, err := l.Accept()
if err != nil {
panic(err.String())
}
handleClient(conn)
}
}
func handleClient(conn net.Conn) {
defer conn.Close()
// a client has connected; now wait for a packet
var msg packet
binary.Read(conn, binary.BigEndian, &msg)
fmt.Printf("Received a packet: %s\n", msg.Data)
// send the response
response := packet{Type: 1, Id: 1}
copy(response.Data[:], "Hello, client")
binary.Write(conn, binary.BigEndian, &response)
}
Here's the client. It sends one packet with packet type 0, id 0, and the contents "Hello, server". Then it waits for a response, prints it, and exits.
package main
import (
"encoding/binary"
"fmt"
"net"
)
type packet struct {
Type int32
Id int32
Data [100]byte
}
func main() {
// connect to localhost on port 2000
conn, err := net.Dial("tcp", ":2000")
if err != nil {
panic(err.String())
}
defer conn.Close()
// send a packet
msg := packet{}
copy(msg.Data[:], "Hello, server")
err = binary.Write(conn, binary.BigEndian, &msg)
if err != nil {
panic(err.String())
}
// receive the response
var response packet
err = binary.Read(conn, binary.BigEndian, &response)
if err != nil {
panic(err.String())
}
fmt.Printf("Response: %s\n", response.Data)
}
答案2
得分: 3
请查看Jan Newmarch的《使用Go进行网络编程》。
英文:
Check out Jan Newmarch's "Network programming with Go".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论