2016-09-29 2 views
2

Я пытаюсь реализовать простой сервер и модель клиента grpc только с помощью метода потоковой передачи на стороне сервера. Я забираю route guide example in offical repo. При попытке запуска я получаю эту ошибку из стороны сервераОшибка выполнения: неверный адрес памяти или разворот указателя nil, пример grpc golang

panic: runtime error: invalid memory address or nil pointer dereference 
[signal 0xb code=0x1 addr=0x0 pc=0x4011fc] 

goroutine 3 [running]: 
panic(0x878c80, 0xc82000a150) 
    /usr/local/go/src/runtime/panic.go:481 +0x3e6 
main.(*server).Podips(0xc820136188, 0xc82000aa40, 0x7f1179b9f530, 0xc82000aa90, 0x0, 0x0) 
    /home/tcs/gowork/src/poc/test/server.go:22 +0x1fc 
poc/test/pb._Getips_Podips_Handler(0x856f00, 0xc820136188, 0x7f1179b9f438, 0xc8201da000, 0x0, 0x0) 
    /home/tcs/gowork/src/poc/test/pb/getip.pb.go:129 +0x175 
google.golang.org/grpc.(*Server).processStreamingRPC(0xc82019a640, 0x7f1179b245a0, 0xc8201ca000, 0xc8201d0000, 0xc820169440, 0xb7afa0, 0xc82016a570, 0x0, 0x0) 
    /home/tcs/gowork/src/google.golang.org/grpc/server.go:689 +0x489 
google.golang.org/grpc.(*Server).handleStream(0xc82019a640, 0x7f1179b245a0, 0xc8201ca000, 0xc8201d0000, 0xc82016a570) 
    /home/tcs/gowork/src/google.golang.org/grpc/server.go:773 +0x1151 
google.golang.org/grpc.(*Server).serveStreams.func1.1(0xc820133020, 0xc82019a640, 0x7f1179b245a0, 0xc8201ca000, 0xc8201d0000) 
    /home/tcs/gowork/src/google.golang.org/grpc/server.go:422 +0xa0 
created by google.golang.org/grpc.(*Server).serveStreams.func1 
    /home/tcs/gowork/src/google.golang.org/grpc/server.go:423 +0x9a 
exit status 2 

и это со стороны клиента

2016/09/29 22:31:37 transport: http2Client.notifyError got notified that the client transport was broken EOF. 
2016/09/29 22:31:37 &{0xc820192b40}.Podips(_) = _, rpc error: code = 13 desc = transport is closing 
exit status 1 

server.go

package main 

import (
    "net" 
    "flag" 
    "fmt" 

    "google.golang.org/grpc/grpclog" 
    "google.golang.org/grpc" 
    pb "poc/test/pb" 
) 

var port = flag.Int("port", 10000, "The server port") 
type server struct{ 
    ip *pb.Ips 
} 

func (s *server) Podips(n *pb.Request, stream pb.Getips_PodipsServer) (error){ 

    res := [3]string{"firstIP", "secondIp", "thirdIP"} 

    for _, v := range res { 

     s.ip.Ip = v 
     if s.ip == nil{ 
      if err := stream.Send(s.ip); err != nil { 
        return err 
      } 
     } 
    } 

    return nil 
} 

func main(){ 
    flag.Parse() 
    lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) 
    if err != nil { 
     grpclog.Fatalf("failed to listen: %v", err) 
    } 
    grpcServer := grpc.NewServer() 
    grpclog.Println("server descrption:%v", grpcServer) 
    pb.RegisterGetipsServer(grpcServer, new(server)) 
    grpcServer.Serve(lis) 

} 

some.proto файл

syntax = "proto3"; 

package getips; 

service Getips { 
    rpc Podips (Request) returns (stream Ips){} 

} 

message Request { 
    string req = 1; 

} 
message Ips { 
    string ip = 1; 
} 

Я прохожу через несколько квестов нс в стеке над потоком около нулевой ошибки указатель Я нашел это peice кода является виновником

s.ip.Ip = v 
if s.ip == nil{ 
    if err := stream.Send(s.ip); err != nil { 
      return err 
    } 

Я не знаю, как решить эту проблему, и я сомневаюсь, что я реализую это неправильный путь. Любая помощь была бы полезна. Thanks

+1

Обратите внимание, что трассировка стека показывает, где именно находится ошибка: '/home/tcs/gowork/src/poc/test/server.go: 22' – JimB

+0

О, спасибо, я этого не видел. Но почему-то я нашел его, проблема в том, что я не знаю, как его решить. –

ответ

0

Вы делаете new(server) без инициализации поля server.ip. Я не знаю подробностей реализации, но вам в первую очередь нужно сначала инициализировать это поле, иначе s.ip будет nil, а когда вы позвоните s.ip.Ip, вы получите сообщение об ошибке.

+0

Спасибо за указание. Но новый (сервер) не проблема. Вместо s.ip.Ip = v я использовал s.ip = {Ip: v}. Это решило это. –

Смежные вопросы