当前位置: 首页 > 知识库问答 >
问题:

客户端无法将数据发送到Golang中的TCP服务器?

庞书
2023-03-14

我有一个TCP服务器和一个客户端,简单的TCP服务器将接收传入的数据并打印出来,而客户端将继续创建一个套接字连接并循环发送数据到TCP服务器。

我得到的信息是,如果一个TCP连接被正确地关闭了,这个过程应该会继续下去,不会发生任何崩溃。

但在从客户端接收到一定数量的数据到服务器之后,客户端会崩溃,并出现错误

total times data send: 16373

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10d7594]

goroutine 1 [running]:
main.sendData()

/Users/apple/Desktop/Personal/umbrellaserver/src/tests/clinet.go:178 
+0xb4
main.main()

/Users/apple/Desktop/Personal/umbrellaserver/src/tests/clinet.go:170 
+0x2a
exit status 2
package main

import (
    "bufio"
    "fmt"
    "net"
    "sync"
)

var wg sync.WaitGroup
var count = 0
var timeX string = ""

var connQueue = make(chan string)

func main() {
    tcpListner := startTCPConnection()
    incomingTCPListener(tcpListner)
}

//startTCPConnection
func startTCPConnection() net.Listener {
    tcpListner, tcpConnectonError := net.Listen("tcp", "localhost:3000")
    if tcpConnectonError != nil {
        print(tcpConnectonError)
        return 
    }
    return tcpListner
}

//incomingTCPListener
func incomingTCPListener(tcpListner net.Listener) {

    for {
        incomingConnection, incomingConnectionError := tcpListner.Accept()
        if incomingConnectionError != nil {
            print(incomingConnectionError)
            return
        }
        wg.Add(1)
        go processIncomingRequest(incomingConnection)
        wg.Wait()
    }
}

//processIncomingRequest
func processIncomingRequest(connection net.Conn) {

    defer connection.Close()

    var scanner = bufio.NewScanner(connection)

    var blob = ""
    for scanner.Scan() {
        fmt.Println("sadd")
        text := scanner.Text()
        blob += text
    }
    print(blob)
    count++
    fmt.Println("totalCount", count)
    wg.Done()
}
package main

import (
    "fmt"
    "net"
)

var count = 0

func testJSON2() string {
    return `Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.`
}

func main() {
    for i := 0; i < 1000000; i++ {
        sendData()
    }

}

func sendData() {

    connection, connectionError := net.Dial("tcp", "localhost:3000")
    defer connection.Close()

    if connectionError != nil {
        fmt.Println(connectionError)
        return 
    }
    newmessage := testJSON2()
    connection.Write([]byte(newmessage + "\n"))
    count++
    fmt.Println(count)
}

有没有什么办法可以避免这次撞车,让它持续运行呢?我是新来的所以如果我犯了什么愚蠢的错误,我很抱歉。

共有1个答案

容远
2023-03-14

首先,如果您想打印到stderr(即您的打印调用),我建议您使用fmt库

fmt.Fprintln(os.Stderr, "hello world")

原因:因为打印功能不能保证保留在该语言中。1

其次,通常使用err这样的名称来给错误命名,您不必拼写出TCPConnectionError这样的错误。

>> sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535

最后,

如果希望避免端口耗尽导致的崩溃:
1。增加端口的临时范围
2。使用Docker,容器在它们自己的网络上,因此使用一组不同的端口,绕过有限的端口范围。
3。在客户端代码中引入一个报价器,以模拟每x秒/分钟一次的连接

package main

import (
    "fmt"
    "net"
    "time"
)

var count = 0

func testJSON2() string {
    return `Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.`
}

func main() {
    max := 1000

    timer1 := time.NewTicker(5 * time.Second)

    i := 0
    for range timer1.C {
        sendData()
        if i == max {
            timer1.Stop()
        }
        i++
    }
}

func sendData() {

    connection, connectionError := net.Dial("tcp", "localhost:3000")
    fmt.Println(connection.LocalAddr())

    if connectionError != nil {
        fmt.Println(connectionError)
        return
    }
    newmessage := testJSON2()
    connection.Write([]byte(newmessage + "\n"))
    count++
    fmt.Println(count)

    err := connection.Close()
    if err != nil {
        fmt.Println(err)
    }
}

引用
^1:https://tip.golang.org/pkg/builtin/#print
^2:MAC上临时端口的范围是什么?
^3:https://www.fromdual.com/humaug-amount-of-time-wait-connections

 类似资料:
  • 我正在试用netty,但当我响应时,客户端似乎没有收到我的消息。我使用Java NIO和socketChannel编写了相同的代码,看起来很好。我这样说是因为客户机会记录我发送的任何内容。下面是我的服务器 下面是我的服务器处理程序 } 示例响应: 我正在我的盒子上做一个tcpdump,我看到了我在电线上发送的内容,所以我不确定我做错了什么。而且,几分钟后,这会被记录下来,我不确定我在服务器或服务器

  • 通常情况下,一切工作正常,但当我在客户机上旋转50个线程,以相同的小数据包(只有39个字节)“同时”访问服务器时,服务器没有接收到所有字节的次数是随机的。更奇怪的是,它是非常一致的如何它不接收他们...只收到5个字节。 我正在使用tcpdump和tcpflow来捕获两端发生的事情(如果不熟悉tcp流,它会从tcp流中去除大量的tcp SYN/ACK/FIN/ETC噪声,并且只向您显示向任一方向发送

  • 我正在Unity中制作一个游戏,我试图将数据从客户端发送到服务器并返回到客户端(试图保存实例),但当我收到数据并尝试将数据发送回客户端时,它表示udp客户端未连接。 它成功地将数据从我的Unity客户端发送到服务器,但一旦它到达那里,套接字就会断开连接,我就无法返回任何内容。正如你所看到的,我试图设置一些多播选项,但它似乎不能正常工作。 客户: 服务器: 因此,服务器中UdpClient的实例会保

  • 我有一个关于Java插座的技术问题。 例如,假设我有一个Java Sockets服务器和n个多个客户端。是否可以几乎实时地将数据从服务器发送到任何或所有客户端? 更准确地说: 有哪种监听器可以在Sockets客户端中实现 有人能告诉我什么方法是最好的吗?此外,如果有人有一个代码示例,我也会很高兴。 谢谢

  • 我需要实现一个TCP服务器,它基本上应该在与客户端握手时打开一个套接字。 套接字打开后服务器需要保持套接字打开,并且能够通过打开的套接字将消息从服务器推送到客户端 我查看了一些spring集成示例,但不确定我所看到的示例是否确实参考了我的需求。 1. Spring集成tcp是否有这种能力来保持打开套接字并将消息从服务器发送到客户端? 服务器还应支持传入请求 客户端实现是作为简单Tcp java客户