123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- package network
- import (
- "fmt"
- "net"
- "time"
- )
- const (
- udpClientReceiveBufferSize = 1024
- )
- type UDPClientResponseCallback func(dataReader *DataReader)
- type UDPClientOption func(opt *UDPClientOptions)
- func WithUDPClientRequestNonBlockCount(count int) UDPClientOption {
- return func(opt *UDPClientOptions) {
- opt.requestNonBlockCount = count
- }
- }
- func WithUDPClientReceiveBufferSize(receiveBufferSize int) UDPClientOption {
- return func(opt *UDPClientOptions) {
- opt.receiveBufferSize = receiveBufferSize
- }
- }
- func WithUDPClientWriteTimeout(timeout time.Duration) UDPClientOption {
- return func(opt *UDPClientOptions) {
- opt.writeTimeout = timeout
- }
- }
- func WithUDPClientReadTimeout(timeout time.Duration) UDPClientOption {
- return func(opt *UDPClientOptions) {
- opt.readTimeout = timeout
- }
- }
- func WithUDPClientResponseCallback(responseCallback UDPClientResponseCallback) UDPClientOption {
- return func(opt *UDPClientOptions) {
- opt.responseCallback = responseCallback
- }
- }
- type UDPClientOptions struct {
-
- requestNonBlockCount int
-
- receiveBufferSize int
-
- writeTimeout time.Duration
-
- readTimeout time.Duration
-
- responseCallback UDPClientResponseCallback
- }
- func NewUDPClientOptions(opts ...UDPClientOption) *UDPClientOptions {
- options := new(UDPClientOptions)
- for _, opt := range opts {
- opt(options)
- }
- if options.receiveBufferSize == 0 {
- options.receiveBufferSize = udpClientReceiveBufferSize
- }
- return options
- }
- type UDPClient struct {
- options *UDPClientOptions
- conn *net.UDPConn
- requestChan chan []byte
- doneChan chan any
- }
- func (client *UDPClient) Connect(serverAddress string, options *UDPClientOptions) error {
- serverAddr, err := net.ResolveUDPAddr("udp", serverAddress)
- if err != nil {
- panic(err)
- }
- conn, err := net.DialUDP("udp", nil, serverAddr)
- if err != nil {
- panic(err)
- }
- client.options = options
- client.conn = conn
- client.requestChan = make(chan []byte, options.requestNonBlockCount)
- client.doneChan = make(chan any)
-
- go client.sendRequest()
- return nil
- }
- func (client *UDPClient) Disconnect() {
- client.doneChan <- nil
- close(client.doneChan)
- client.doneChan = nil
- close(client.requestChan)
- client.requestChan = nil
- closeConnection(client.conn)
- client.conn = nil
- }
- func (client *UDPClient) Send(data []byte) {
- client.requestChan <- data
- }
- func (client *UDPClient) sendRequest() {
- dealRequestDoneChannels := make([]chan any, 0)
- for {
- select {
- case <-client.doneChan:
- for _, dealRequestDoneChan := range dealRequestDoneChannels {
- dealRequestDoneChan <- nil
- close(dealRequestDoneChan)
- }
- return
- case data := <-client.requestChan:
- err := writeUDP(client.conn, data, withWriteDeadline(client.options.writeTimeout))
- if err != nil {
- fmt.Println(err)
- continue
- }
- if client.options.responseCallback != nil {
- responseBytes, _, err := readUDP(client.conn, client.options.receiveBufferSize, withReadDeadline(client.options.readTimeout))
- if err != nil {
- fmt.Println(err)
- continue
- }
- go client.options.responseCallback(NewDataReader(responseBytes))
- }
- }
- }
- }
|