【问题标题】:Go issue with strings字符串问题
【发布时间】:2011-11-07 03:40:45
【问题描述】:

我在 Golang 中遇到了一些字符串问题。似乎它们没有被移交给另一个函数。

func Sendtext(ip string, port string, text string) (err int) {
targ := ip + ":" + port
raddr,e := net.ResolveTCPAddr("tcp",targ)
if e != nil {
    os.Stdout.WriteString(e.String()+"\n")
    return 1
}
conn,e := net.DialTCP("tcp",nil,raddr)
if e != nil {
    os.Stdout.WriteString(e.String()+"\n")
    return 1
}
conn.Write([]byte(text))
mess := make([]byte,1024)
conn.Read(mess)
message := string(mess)
conn.Close()
if message[0] == 'a' {
    return 0
} else {
    return 1
}
return 0
}

func main() {
os.Stdout.WriteString("Will send URL: ")
url := GetURL()
os.Stdout.WriteString(url + "\n\n")
_, port, pass, ip := browserbridge_config.ReadPropertiesFile()
os.Stdout.WriteString("sending this url to " + ip + ":" + port + "\n")
message := url + "\n" + pass + "\n"
os.Stdout.WriteString("\nsending... ")
e := Sendtext(ip, port, message)
if e != 0 {
    os.Stdout.WriteString("ERROR\n")
    os.Exit(e);
}
os.Stdout.WriteString("DONE\n")
}

和我的配置阅读器:

func ReadConfigFile(filename string) (browsercommand string, port string, pass string, ip string) {

// set defaults
browsercommand = "%u"
port = "7896"
pass = "hallo"
ip = "127.0.0.1"

// open file
file, err := os.Open(filename)
if err != nil {
    os.Stdout.WriteString("Error opening config file. proceeding with standard config...")
    return
}


// Get reader and buffer
reader := bufio.NewReader(file)

for {
    part,_,err := reader.ReadLine()
    if err != nil {
        break
    }
    buffer := bytes.NewBuffer(make([]byte,2048))
    buffer.Write(part)
    s := strings.ToLower(buffer.String())

    if strings.Contains(s,"browsercommand=") {
        browsercommand = strings.Replace(s,"browsercommand=","",1)
    } else {
        if strings.Contains(s,"port=") {
            port = strings.Replace(s,"port=","",1)
        } else {
            if strings.Contains(s,"password=") {
                pass = strings.Replace(s,"password=","",1)
            } else {
                if strings.Contains(s,"ip=") {
                    ip = strings.Replace(s,"ip=","",1)
                }
            }
        }
    }
}

return
}

这个程序的输出:

Will send URL: test.de

sending this url to 192.168.2.100:7896

sending... 
dial tcp 192.168.2.1:0: connection refused
ERROR

(192.168.2.1 是网关)

我在 Sendtext 的顶部尝试了 os.Stdout.WriteString(targ) 或 os.Stdout.WriteString(ip),但没有输出。

关于它的令人困惑的事情:昨天它工作 xD(在我将 ReadConfig 迁移到它自己的 .go 文件之前)

希望你能帮我解决这个问题...

锡拉尔


更新:

正如 PeterSO 所说,问题不在于琴弦的交接 我的第一个猜测,它必须是字符串到 TCPAddr 的转换,这是真的,但它似乎是字符串的问题,而不是网络库的问题。 我刚刚添加 ip = "192.168.2.100" 端口 = "7896" 在调用 Sendtext 之后,这很有帮助...(至少在用户需要设置自定义 ip/port 之前...)

我知道当我决定从 goconf (http://code.google.com/p/goconf/) 切换到我自己的时,问题就出现了。这就是我认为问题出在 ReadProperties() 函数的原因。

我还意识到 strconv.Atoi(port) 返回 0(解析“7896”:无效参数) 当我使用具有已实现(不可更改)配置的服务器和客户端,然后让客户端从配置文件中读取密码时,密码比较失败。当我还在代码中正确设置密码时(不读取文件),它可以工作。

我现在真的不知道该怎么办......有什么想法吗?

【问题讨论】:

    标签: string go


    【解决方案1】:

    Go 字节包:func NewBuffer(buf []byte) *Buffer

    NewBuffer 使用buf 创建并初始化一个新的Buffer 初始内容。打算准备一个Buffer来阅读 现有数据。它也可以用于调整内部缓冲区的大小 写作。为此,buf 应该具有所需的容量,但 长度为零。

    在大多数情况下,new(Buffer)(或者只是声明一个Buffer 变量) 优于NewBuffer。特别是,传递一个非空的 buf 到NewBuffer,然后写到Buffer 将覆盖buf, 不要附加到它上面。

    在你的ReadConfigFile 函数中,你写:

    buffer := bytes.NewBuffer(make([]byte,2048))
    buffer.Write(part)
    

    make([]byte,2048) 函数调用为buffer 创建一个长度和容量为 2048 字节的初始切片。 buffer.Write(part) 函数调用通过覆盖buffer 写入part。至少,您应该编写 make([]byte,0,2048) 以最初为 buffer 切片指定长度为零和容量为 2048 字节的切片。

    您的ReadConfigFile 函数还有其他缺陷。例如,key=value 格式非常严格,只识别硬编码到函数中的键,如果没有给出配置文件则不返回默认值,配置文件不关闭等。这是一个基本的实现配置文件阅读器。

    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "strings"
    )
    
    type Config map[string]string
    
    func ReadConfig(filename string) (Config, os.Error) {
        config := Config{
            "browsercommand": "%u",
            "port":           "7896",
            "password":       "hallo",
            "ip":             "127.0.0.1",
        }
        if len(filename) == 0 {
            return config, nil
        }
        file, err := os.Open(filename)
        if err != nil {
            return nil, err
        }
        defer file.Close()
        rdr := bufio.NewReader(file)
        for {
            line, err := rdr.ReadString('\n')
            if eq := strings.Index(line, "="); eq >= 0 {
                if key := strings.TrimSpace(line[:eq]); len(key) > 0 {
                    value := ""
                    if len(line) > eq {
                        value = strings.TrimSpace(line[eq+1:])
                    }
                    config[key] = value
                }
            }
            if err == os.EOF {
                break
            }
            if err != nil {
                return nil, err
            }
        }
        return config, nil
    }
    
    func main() {
        config, err := ReadConfig(`netconfig.txt`)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println("config:", config)
        ip := config["ip"]
        pass := config["password"]
        port := config["port"]
        fmt.Println("values:", ip, port, pass)
    }
    

    输入:

    [a section]
    key=value
    ; a comment
    port = 80
      password  =  hello  
     ip= 217.110.104.156
    # another comment
     url =test.de
    file =
    

    输出:

    config: map[browsercommand:%u key:value port:80 ip:217.110.104.156 url:test.de
    file: password:hello]
    values: 217.110.104.156 80 hello
    

    【讨论】:

    • 谢谢,我知道所有这些问题。这是我第一次尝试直接从文件本身读取文件……我首先想在改进程序之前解决这个问题。我不会复制你的整个代码,因为我想自己做(但谢谢)。我谈到了“您的 ReadConfig 函数还有其他缺陷”之后的部分...关于 make funktion 和缓冲区的提示:谢谢。
    【解决方案2】:

    将以下语句插入到 main 函数中调用 Sendtext 函数之前的语句。

    fmt.Println("\nmain:", "\nip = |", ip, "| \nport = |", port, "| \ntext = |", message, "|")
    

    输出应该是这样的:

    main: 
    ip = | 192.168.2.100 | 
    port = | 7896 | 
    text = | test.de
    hallo
     |
    

    Sendtext 函数中插入以下语句作为第一条语句。

    fmt.Println("\nSendtext:", "\nip = |", ip, "| \nport = |", port, "| \ntext = |", text, "|")
    

    输出应该是这样的:

    Sendtext: 
    ip = | 192.168.2.100 | 
    port = | 7896 | 
    text = | test.de
    hallo
     |
    

    正如预期的那样,参数是按值传递给参数的。

    【讨论】:

    • 好的,问题似乎是转换为 TCPAddr...我现在正在尝试修复它...
    【解决方案3】:

    解决了。问题是将 2048 长的 []byte 转换为字符串。这使得字符串长度相等,但后面有很多 NIL 字符。 所以在 ReadConfig() 结束时对所有值运行 ip = strings.Replace(ip,string(0),"",-1) 解决了这个问题。

    【讨论】:

    • 你没有修复真正的错误!首先不要创建 2048 个零字节!有关详细信息,请参阅我的第二个答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2019-01-31
    • 1970-01-01
    • 2021-12-13
    相关资源
    最近更新 更多