1
votes

NOTE

I rewrote this question for the bounty as i was able to figure out how to get the first question solved but didn't want to start a new question. the comments below pertain to the original question, not the revised.

Description of Issue

My tcp client executes querying the tcp server one time successfully, returns the response, and then subsequent requests to the server from the client fails. Also, if i terminate the client and reload it fails on the first attempt as well.

Here's what my command prompt looks like:

root@ubuntuT:/home/jon/gocode/udps#  ./udpservtcpclient 
Text to send: SampleQuery
Message from server: SampleResponse
Text to send: SampleQuery
((End - No Response))
root@ubuntuT:/home/jon/gocode/udps# ./udpservtcpclient 
Text to send: SampleQuery
((End - No Response))

What I expect

I expect to be able to query the tcp server from the tcp client endlessly, and have the tcp server return a response from the UDP Server every time. Also, if i terminate the tcp client and reload it should also query correctly to the tcp server without hiccups.

What I think

Something is incorrect with the tcp server accepting connections. I moved the UDP Portion in separate code (not here as not important still does not work) to its own function which opens and closes UDP connections and it still does not function after first connection.

UPDATE

I updated the code to display "Accepted Connection" just below c,err:=serverConn.Accept() and it only printed once, for the first request. any subsequent queries from the client did not display the line so it has to do with accepting connections

Sourcecode

Server Code:

package main

import (
  "log"
  //"fmt"
  "net"
  //"strings"
  "bufio"
  //"time"
  //"github.com/davecgh/go-spew/spew"
)

var connUDP *net.UDPConn

func udpRoutine(query string)(string){
  connUDP.Write([]byte(query))
  buf:= make([]byte,128)
  n,err:=connUDP.Read(buf[0:])
  if err != nil{
    log.Fatal(err)
  }
  response := string(buf[0:n])
  return response
}

func handle(conn net.Conn) error {
  defer func(){
    conn.Close()
  }()
  r := bufio.NewReader(conn)
  w := bufio.NewWriter(conn)
  scanr := bufio.NewScanner(r)
  for {
    scanned := scanr.Scan()
    if !scanned {
      if err := scanr.Err(); err != nil {
    log.Printf("%v(%v)", err, conn.RemoteAddr())
    return err
      }
      break
    }
    response:=udpRoutine(scanr.Text())
    w.WriteString(response+"\n")
    w.Flush()
  }
  return nil
}

func main(){

   // setup tcp listener
   serverConn,err := net.Listen("tcp","127.0.0.1:8085")
   if err != nil{
    log.Fatal(err)
   }
   defer serverConn.Close()

   // setup udp client
   udpAddr,err:=net.ResolveUDPAddr("udp4","127.0.0.1:1175")
   if err != nil{
    log.Fatal(err)
   }
   connUDP,err=net.DialUDP("udp",nil,udpAddr)
   if err != nil{
    log.Fatal(err)
   }
   defer connUDP.Close()

   for{
      c,err:=serverConn.Accept()
      if err != nil{
    log.Fatal(err)
      }
      //c.SetDeadline(time.Now().Add(5))
      go handle(c)
    }
  }

Client Code:

package main

import "net"
import "fmt"
import "bufio"
import "os"

func main() {

  // connect to this socket
  conn, _ := net.Dial("tcp", "127.0.0.1:8085")
  for { 
    reader := bufio.NewReader(os.Stdin)
    // read in input from stdin
    fmt.Print("Text to send: ")
    text,_ := reader.ReadString('\n')
      // send to socket
    fmt.Fprintf(conn, text + "\n")
    // listen for reply
    message, _ := bufio.NewReader(conn).ReadString('\n')
    fmt.Print("Message from server: "+message)
  }
}
1
Comments are not for extended discussion; this conversation has been moved to chat.user3956566
Just to start you off, you're still doing what was mentioned multiple times in the previous conversation and creating bufio.Readers in a for loop. You cannot do that. In this latest incarnation, I suspect the rest of the problems are related to your inconsistent handling of newlines, sometimes stripping them with a scanner, sometimes retaining them with ReadString, sometimes writing extras like in Fprint and WriteString.JimB
@JimB Yes I realized that after relooking at the conversation. Its been fixed. Sorry for the issues.somejkuser
@JimB Ill look at the remaining issues tomorrow including new lines. I appreciate your assistance. Im very new to Go so im sorry for the issues.somejkuser

1 Answers

2
votes

It seems there are two problems here:

1) UDP Server

Your question describes an issue when the client is not able to make a second request to the server.

I used a simple echo UDP server, along with the code you posted for the server and client and can't reproduce the problem (I can still make several requests to the server), so I suspect that has to do with the UDP server you are using (code for which I can't see in this question).

I suggest you try this with a simple UDP server that just echoes messages back:

package main

import (
    "fmt"
    "net"
)

func main() {
    conn, _ := net.ListenUDP("udp", &net.UDPAddr{IP:[]byte{0,0,0,0},Port:1175,Zone:""})
    defer conn.Close()
    buf := make([]byte, 1024)
    for {
        n, addr, _ := conn.ReadFromUDP(buf)
        conn.WriteTo(buf[0:n], addr)
        fmt.Println("Received ", string(buf[0:n]), " from ", addr)
    }
}

2) Extra new line in TCP Client

Using the exact code you posted and that UDP server I posted above, this seems to work, but the output I get on the client is not what I would have expected.

It seems that is cause by a second issue which is this line in the client:

// send to socket
fmt.Fprintf(conn, text + "\n")

That line end you are sending is causing the scanner you use on the server to read two lines (the text you send and then an empty line), making the server write two lines back to the client.

But in the client you only read one line, so the second line seems to be pending until the client connects again.

That can be fixed by simply changing that to:

// send to socket
fmt.Fprintf(conn, text)

Output for the fixed code

Using that UDP server and making that change to the client, this is the output I get when running all three components:

Text to send: first msg
Message from server: first msg
Text to send: second msg
Message from server: second msg
Text to send: third msg
Message from server: third msg
Text to send: 

I can then stop just the client, start it again and it'd keep working:

Text to send: fourth msg
Message from server: fourth msg
Text to send: 

Aditional notes

About the two other lines in the client code that use newlines:

// read in input from stdin
fmt.Print("Text to send: ")
text,_ := reader.ReadString('\n')

That newline is needed there, cause when you input the text using standard input, you finish the line using the enter key (and thus ending the line with a newline), so the line should be read until the \n character.

message, _ := bufio.NewReader(conn).ReadString('\n')

That one is needed cause when the server writes the response to the connection it does w.WriteString(response+"\n"). So the response includes a newline at the end, and you should read up to that newline when reading the response text.