2016-03-30 7 views
0

2つのポートをリッスンし、2つのポート間でメッセージを転送するサーバーがあります。唯一の問題は、各クライアント(または各ポート)が、別のポートが送信した前のメッセージを受信する前にメッセージを送信する必要があることです。たとえば、クライアント1が「hello」と言う場合、クライアント2は最初にメッセージを送信しない限り、メッセージを受信しません。1つ前にメッセージを受け入れる

私は、各クライアントが新しいメッセージを送信する前に以前のメッセージを受信する必要があるようにする方法を見つけたいと思います。 (クライアント1が何かを言うまで、クライアント1は何も受け取らないので、プレースホルダテキストを含む文字列を送る予定です)。

誰でもこの問題について助けてくれますか?私は自分のリスニングコードと私のコードを各クライアントのためのメッセージを自分の行くルーチンに書くことを試みますが、それは仕事をしませんでした。どんな助けもありがとう。ローカルホスト: "3000 localhost" を「に置き換えられ

package main 

import (
    "fmt" 
    "log" 
    "net" 
) 

var message string = "Client 2 is receiving your message" 

func main() { 
    fmt.Println("The server is listening on Port 3000 and 8080") 
    //Set up listeners for the ports each client is using 
    listener, err := net.Listen("tcp", "localhost:3000") 
    if err != nil { 
     log.Fatal(err) 
    } 
    listener2, err := net.Listen("tcp", "localhost:8080") 
    if err != nil { 
     log.Fatal(err) 
    } 
    go acceptLoop(listener) 
    acceptLoop(listener2) // run in the main goroutine 
} 

func acceptLoop(l net.Listener) { 
    defer l.Close() 
    for { 
      c, err := l.Accept() 
      if err != nil { 
       log.Fatal(err) 
      } 
      fmt.Println("New connection found!") 
      go listenConnection(c) 
    } 
} 

func listenConnection(conn net.Conn) { 
     fmt.Println("Yay") 
     for { 
       buffer := make([]byte, 1400) 
       dataSize, err := conn.Read(buffer) 
       if err != nil { 
        fmt.Println("Connection has closed") 
        return 
       } 

       //This is the message you received 
       data := buffer[:dataSize] 
       fmt.Print("Received message: ", string(data)) 

       // Send the message back 
       _, err = conn.Write([]byte(message)) 
       if err != nil { 
         log.Fatalln(err) 
       } 
       fmt.Print("Message sent: ", string(data)) 
       message = string(data) 
     } 
} 

クライアント1つの

package main 

import (
     "fmt" 
     "log" 
     "net" 
     "bufio" 
     "os" 
) 

func main() { 
     conn, err := net.Dial("tcp", "localhost:3000") 
     if err != nil { 
       log.Fatalln(err) 
     } 

for { 
     reader := bufio.NewReader(os.Stdin) 
     fmt.Print("Enter text: ") 
     text, _ := reader.ReadString('\n') 

     _, err = conn.Write([]byte(text)) 
     if err != nil { 
       log.Fatalln(err) 
     } 

     for { 
       buffer := make([]byte, 1400) 
       dataSize, err := conn.Read(buffer) 
       if err != nil { 
         fmt.Println("The connection has closed!") 
         return 
       } 

       data := buffer[:dataSize] 
       fmt.Println("Received message: ", string(data)) 
       break 
     } 

    } 
} 

私の2番目のクライアントは除いて私の最初のと同じである

サーバー:ここ

は私のコードです:8080 "。

私は助けていただきありがとうございます!私はかなりネットワーキングと移動に新しいので、ヒントは素晴らしいでしょう。

答えて

0

今、あなたのServerはちょうどエコーです。クライアントから受信したメッセージで応答します。

2つのクライアント間でメッセージを中継したい場合は、3つのクライアントが接続されている場合(最初のポートに2つ、もう一方には1つ)に何が起こるべきかをまず理解する必要があります。

あなたはこのような何か(-go-コード擬似)を行うことができ、各ポートに接続されているただ一つのクライアント持つことが予想される場合:

func main() { 
    // ... 
    # Channels must be buffered or else clients will deadlock. 
    relay := make(chan string, 1) 
    go acceptLoop(listener1, relay) 
    acceptLoop(listener2, relay) 
} 

func acceptLoop(l, relay) { 
    for { 
    conn := l.Accept() 
    for { 
     relay <- conn.Read() 
     conn.Write(<-relay) 
    } 
} 
+0

を私が使用している場合、私はまだ私のlistenConnection()関数が必要になりますチャンネル?クライアントプログラムを変更する必要がありますか? – user6126174

+0

一度に1つのリスナごとに1つのクライアントだけを処理する場合は、 'listenConnection'は必要ありません。 TCPはストリーミングプロトコルであり、非区切りの読み取り/書き込みプロトコルは、それらの間のかなりの遅延を伴う短いメッセージに対してのみ機能することを認識していると仮定して、クライアントは問題ありません。 – szym

+0

だから私は文字列チャンネルを作る必要があります。次に、リスナーに加えて文字列チャネルを取得するためにacceptLoop()を変更する必要があります。 AcceptLoopは接続をリッスンし、前後に文字列を渡します。これは正しいです?もう1つの注意点として、文字列チャネルは[]バイトチャネルである必要があります。これは、チャネルがメッセージを送信する方法であるためです。 – user6126174

関連する問題