3 回答
TA贡献1865条经验 获得超7个赞
首先,如果你想打印到 stderr,(即你的打印调用),我建议使用 fmt 库
fmt.Fprintln(os.Stderr, "hello world")
为什么:因为打印功能不能保证留在语言中。1个
其次,通常的做法是将错误名称命名为err,而不必将错误拼写为tcpConnectionError.
connection, connectionError := net.Dial("tcp", "localhost:3000")第三,由于您在服务器中使用 tcp,因此正在侦听 ipv6 和 ipv4。我至少在 Windows 机器上观察到连接打开两个连接,一个用于 ipv4 和 ipv6,然后丢弃 ipv6 连接以支持 ipv4。
最后,当 TCP 连接关闭时,端口不能立即重新使用,因为操作系统必须等待 TIME_WAIT 间隔(最大段生存期,MSL)的持续时间。
您的客户端代码正在打开大量非常短暂的 tcp 连接,并且根据您临时端口范围的范围,您的代码可能会或可能不会崩溃。从16373的数量来看,你有默认范围。2个
>> 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)
}
}
TA贡献1852条经验 获得超7个赞
if connectionError != nil {
fmt.Println(connectionError)
return
}
defer connection.Close()
defer connection.Close() 应该在错误检查之后,因为连接变量可以是 nil incase 拨号返回时出现一些错误。
TA贡献1853条经验 获得超9个赞
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)
wg.Wait()
}
//startTCPConnection
func startTCPConnection() net.Listener {
tcpListner, tcpConnectonError := net.Listen("tcp", "localhost:3000")
if tcpConnectonError != nil {
print(tcpConnectonError)
// return
log.Fatal(tcpConnectonError)
}
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()
}
问题出在server.go。我的猜测是您通过在 incomingTCPListener() 函数中调用 wg.Wait() 而不是 main() 来耗尽端口。此外,在 startTCPConnection() 函数中直接返回将导致编译器错误。
- 3 回答
- 0 关注
- 119 浏览
添加回答
举报