полный код можно скачать на https://groups.google.com/forum/#!topic/golang-nuts/e1Ir__Dq_gE
Может ли кто-нибудь помочь мне улучшить этот пример кода до нуля?
Я думаю, что это поможет нам разработать бесплатный клиент / серверный код без ошибок.
мои шаги разработки:
- Создайте сервер, который может обрабатывать несколько соединений с помощью goroutine.
- Создайте клиент, который отлично работает с простым протоколом.
- Развернуть клиент для имитации нескольких клиентов (с параметром -n = 1000 клиентов по умолчанию)
- TODO: попытаться уменьшить блокировку сервера
- TODO: попробуйте использовать bufio для повышения пропускной способности
Я нашел этот код очень нестабильным, содержит три проблемы:
- запуск 1000 клиентов, у одного из них происходит EOF при чтении с сервера.
- Запустите 1050 клиентов, скоро получите слишком много открытых файлов (клиенты не открылись).
запуск 1020 клиентов, ошибка выполнения с длинными стеками трассировки.
Start pollServer: pipe: too many open files
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x28 pc=0x4650d0]
Здесь я вставляю свой более упрощенный код.
const ClientCount = 1000
func main() {
srvAddr := "127.0.0.1:10000"
var wg sync.WaitGroup
wg.Add(ClientCount)
for i := 0; i < ClientCount; i++ {
go func(i int) {
client(i, srvAddr)
wg.Done()
}(i)
}
wg.Wait()
}
func client(i int, srvAddr string) {
conn, e := net.Dial("tcp", srvAddr)
if e != nil {
log.Fatalln("Err:Dial():", e)
}
defer conn.Close()
conn.SetTimeout(proto.LINK_TIMEOUT_NS)
defer func() {
conn.Close()
}()
l1 := proto.L1{uint32(i), uint16(rand.Uint32() % 10000)}
log.Println(conn.LocalAddr(), "WL1", l1)
e = binary.Write(conn, binary.BigEndian, &l1)
if e == os.EOF {
return
}
if e != nil {
return
}
// ...
}