第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Go 中關(guān)閉客戶端服務(wù)器通信

在 Go 中關(guān)閉客戶端服務(wù)器通信

Go
慕桂英3389331 2022-10-17 10:09:51
我創(chuàng)建了這個服務(wù)器,它通過將它連接到端口 8080 與 PuTTY 客戶端發(fā)送該服務(wù)器接收的數(shù)據(jù)。現(xiàn)在我想用頻道關(guān)閉所有東西,我該怎么做?寫完“退出”。全部用 Golang 編寫。package mainimport (    "bufio"    "fmt"    "net")func main() {    //Ascolta richiesta    datastream, err := net.Listen("tcp", ":8080")    if err != nil {        fmt.Println(err)        return    }    defer datastream.Close()    //Accetta richiesta    for {        connessione, err := datastream.Accept()        if err != nil {            fmt.Println(err)            return        }        go handle(connessione)    }}//Connessione Handle > Threadfunc handle(connessione net.Conn) {    scanner := bufio.NewScanner(connessione)    for scanner.Scan() {        data := scanner.Text()        fmt.Printf("%q\n", data)        if data == "exit" {            connessione.Close()        }    }    if err := scanner.Err(); err != nil {        fmt.Println("error", err)    }}
查看完整描述

1 回答

?
MMTTMM

TA貢獻1869條經(jīng)驗 獲得超4個贊

免責(zé)聲明,可能有更好的方法來做到這一點,但這是我想出的。

主要挑戰(zhàn)是關(guān)閉所有連接。這具有挑戰(zhàn)性的原因是因為我們只能在不等待Read網(wǎng)絡(luò)連接的情況下檢查通道。默認(rèn)情況下,網(wǎng)絡(luò)連接上的讀取將始終阻塞,直到發(fā)送數(shù)據(jù)或從另一端關(guān)閉它們。

我們可以使用readDeadline在設(shè)定的時間返回網(wǎng)絡(luò)連接的讀取。這允許我們檢查通道是否仍然每 x 秒打開一次,如果我們在每次超過期限時都繼續(xù)延長期限。

現(xiàn)在我們可以關(guān)閉共享通道來終止所有連接。這將占用配置的超時時間。另請注意,一旦頻道關(guān)閉,您將無法重新打開它,如果您想在“退出”命令后接受連接,則必須創(chuàng)建一個新頻道。如果您想將此作為正常關(guān)閉的一部分,則無需執(zhí)行此操作,并且可以忽略重置退出通道的 goroutine。

我們最終得到類似的東西:

package main


import (

    "bufio"

    "errors"

    "fmt"

    "io"

    "net"

    "os"

    "time"

)


func main() {


    //Ascolta richiesta

    datastream, err := net.Listen("tcp", ":8080")


    if err != nil {

        fmt.Println(err)

        return

    }

    defer datastream.Close()


    // Make a channel on which we can't send any data, just close it

    exit := make(chan struct{})


    // Replace the closed channel with a new channel so we can accept new connection again. (optional)

    go func() {

        for {

            <-exit

            exit = make(chan struct{})

            fmt.Println("recreate chan")

        }

    }()


    //Accetta richiesta

    for {

        connessione, err := datastream.Accept()

        if err != nil {

            fmt.Println(err)

            return

        }


        // Give the channel to every connection

        go handle(connessione, exit)

    }


}


//Connessione Handle > Thread

func handle(connessione net.Conn, exit chan struct{}) {


    // Set the read timeout, this will cause the connection to return an os.ErrDeadlineExceeded error

    // every 5 seconds if no data read in that time.

    timeoutEvery := 5 * time.Second

    err := connessione.SetReadDeadline(time.Now().Add(timeoutEvery))

    if err != nil {

        fmt.Println("error", err)

    }


    // This pipe will allow us to copy data from the Network connection to the scanner without the scanner

    // via this goroutine.

    r, w := io.Pipe()

    // Close the pipeReader after we are done

    defer func() {

        r.Close()

    }()

    go func() {

        // Close the pipe and network connection when returning

        defer func() {

            fmt.Println("connection closed")

            connessione.Close()

            w.Close()

        }()


        // Allocate a buffer for the copy

        b := make([]byte, 32*1024)

        for {

            select {

            case <-exit:

                // If exit has been closed, we will enter this case

                return

            default:

                // If exit is still open, we enter this case.


                // Copy data from the connection to the pipe writer, use CopyBuffer to avoid temporary

                // buffer allocation(speed improvement)

                _, err := io.CopyBuffer(w, connessione, b)

                if err != nil {

                    // If an error is returned, check if this is due to the read deadline

                    if errors.Is(err, os.ErrDeadlineExceeded) {

                        // If it is, just extend it by our timeout again

                        err := connessione.SetReadDeadline(time.Now().Add(timeoutEvery))

                        if err != nil {

                            fmt.Println("error", err)

                            return

                        }


                        continue

                    }


                    // If there is any other error, close the connection.


                    fmt.Println("error", err)

                    return

                }

            }

        }

    }()


    scanner := bufio.NewScanner(r)


    for scanner.Scan() {

        data := scanner.Text()

        fmt.Printf("%q\n", data)

        if data == "exit" {

            // Close the exit channel, this will cause all goroutines to close the network connections

            // and the handlers to exit.

            close(exit)

        }


    }


    if err := scanner.Err(); err != nil {

        fmt.Println("error", err)

    }


    fmt.Println("handle return")

}


查看完整回答
反對 回復(fù) 2022-10-17
  • 1 回答
  • 0 關(guān)注
  • 155 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號