2016-11-02 5 views
1

Ich habe ein Problem mit Java-Socket und Golang getroffen. Ich versuche, einen Golang-Server zu entwickeln, der Byte-Array an einen Android-Client sendet/empfängt. jetzt kann der android-client byte-array an go-server senden, kann aber nichts von go-server empfangen. Ich habe den folgenden Code angehängt.Golang-Server senden Byte-Array an Android

Der Code blieb stecken, wenn reach in.read(); Ich versuchte in.available(), um zu sehen, wieviele Bytes im Eingangsstrom sind. es zeigt immer 0:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Button regButton = (Button) findViewById(R.id.regbut); 
    msg = (TextView) findViewById(R.id.msg); 

    regButton.setOnClickListener(new View.OnClickListener(){ 
     @Override 
     public void onClick(View view){ 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        byte[] array; 
        BigInteger mykey = mykey(publicKey); 
        System.out.println(mykey); 
        BigInteger rawkey = generater.modPow(mykey,publicKey); 
        BigInteger serverRawKey; 
        System.out.println(rawkey); 
        array = rawkey.toByteArray(); 
        System.out.println(rawkey.bitCount()); 
        try{ 
         Socket con = new Socket("149.166.134.55",9999); 
         OutputStream out = con.getOutputStream(); 
         InputStream in = con.getInputStream(); 
         DataOutputStream dOut = new DataOutputStream(out); 
         //DataInputStream din = new DataInputStream(in); 
         byte[] data = new byte[10]; 
         dOut.write(array); 
         TimeUnit.SECONDS.sleep(10); 
         System.out.println(in.available()); 
         in.read(data); 
         con.close(); 
         }catch (Exception e){ 
         System.out.println(e); 
         } 
        } 
       }).start(); 
      } 
     }); 
     } 

hier ist der go-code. wenn ich in.read() entferne; In Java funktioniert alles gut. aber es pausiert, wenn ich in.read() hinzufüge;

var publickey *big.Int 

func ClientListen(port string) { 
    ln, err := net.Listen("tcp", port) 
    if err != nil { 
     fmt.Println("error\n") 
     fmt.Println(err) 
     return 
    } 
    for { 
     nc, err := ln.Accept() 
     if err != nil { 
      fmt.Println(err) 
      continue 
     } 
     go recivemsg(nc) 
    } 
} 

func recivemsg(nc net.Conn) { 
    publickey = big.NewInt(15485863) 
    var msg []byte 
    var buf bytes.Buffer 
    rawkey := big.NewInt(0) 
    io.Copy(&buf, nc) 
    fmt.Println("total size:", buf.Len()) 
    msg = buf.Bytes() 
    rawkey = rawkey.SetBytes(msg) 
    fmt.Println(msg, " ", rawkey) 
    r := rand.New(rand.NewSource(99)) 
    myraw := big.NewInt(0) 
    myraw = myraw.Rand(r, publickey) 
    fmt.Println(myraw) 
    newmsg := myraw.Bytes() 
    nc.Write(newmsg) 
    nc.Close() 
    fmt.Println(nc.RemoteAddr()) 

} 

func main() { 
    ClientListen(":9999") 
} 

Danke Jungs für Ihre Zeit nehmen, meine Frage

+0

Ihr Go-Code basiert auf dem Schließen der Verbindung, um das Ende der Nachricht zu signalisieren. Der Absender muss die Verbindung entweder schließen, oder Sie benötigen ein anderes Protokoll zum Abgrenzen von Nachrichten. – JimB

+0

also muss ich eine andere Verbindung herstellen, um die Nachricht an Java zu senden? –

+0

Nein, Sie brauchen nur ein Protokoll zum Senden von Nachrichten: feste Länge, Länge vorangestellt, Newline-abgegrenzt, http, etc. Eine TCP-Verbindung ist ein Stream, es sendet keine einzelnen Nachrichten. – JimB

Antwort

0

io.Copy(&buf, nc) auf Go Seite lesen wird weiterhin von der Verbindung des Eingangsstroms lesen, bis es geschlossen ist. Auf der Java-Seite versuchen Sie, aus dem Eingangsstrom der Verbindung zu lesen, aber die Go-Seite wartet immer noch auf weitere Eingaben, da Java immer noch seine Ausgangsdämpfung (Go's Eingangsstrom) offen hält.

Lösung: Schließen Sie auf der Java-Seite den Ausgabestream mit der Methode shutdownOutput() des Sockets, nachdem Sie mit dem Schreiben fertig sind.

+1

Ich habe socket.shutdownOutput() verwendet und es funktioniert für mich. für jeden, der die ähnliche Frage hat, benutze outputstream.close(); Es wird die gesamte Steckdose herunterfahren. –

+0

Dank @ ZhijieLi für das wichtige Detail! – janos