Reputation: 31
I am new in Go and I am trying to create a server which can receive a message from a client and send it to other client or any other specific client. I have tried many chat examples but what I wanted to do is to create two files where one is for server and another is for the client. This is the code I tried so far.
server.go
package main
import "net"
import "fmt"
import "bufio"
import "strings"
func send(c net.Conn){
netData, err := bufio.NewReader(c).ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
temp := strings.TrimSpace(string(netData))
fmt.Printf(temp)
}
func main() {
fmt.Println("Launching server...")
// listen on all interfaces
ln, _ := net.Listen("tcp", ":8081")
for {
// Listen for an incoming connection.
conn, err := ln.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
continue
}
go send(conn)
}
client.go
package main
import "net"
import "fmt"
import "bufio"
import "os"
func recieve(conn net.Conn){
message, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Println(message)
}
func send(conn net.Conn){
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n')
fmt.Fprintf(conn, text)
}
func main(){
// connect to this socket
conn, err := net.Dial("tcp", "127.0.0.1:8081")
if err != nil {
fmt.Println("Error accepting: ", err.Error())
}
for {
go recieve(conn)
go send(conn)
}
conn.Close()
}
When I try to run that my computer crashed. I understand I am making some mistake for handling the send & received message but couldn't able to figure it out. I will appreciate any kind of help. Thanks.
Upvotes: 0
Views: 1266
Reputation: 31
I have modified the client side in this way. Called a goroutine function 'receive' in the main function.
package main
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
// connect to this socket
conn, err := net.Dial("tcp", "127.0.0.1:8081")
if err != nil {
fmt.Println("Error accepting: ", err.Error())
}
go receive(conn)
sc := bufio.NewScanner(os.Stdin)
for sc.Scan() {
if sc.Err() != nil {
fmt.Println("scanner error!")
}
txt := sc.Text()
// It is important to append "newline" here because you are
// using the "ReadString('\n')" method on the server side.
// Otherwise, the program would stuck at the "readstring"
// method.
b := []byte(txt + "\n")
_, err := conn.Write(b)
if err != nil {
fmt.Println("Failed to send data to the server!")
break
}
}
conn.Close()
}
func receive(c net.Conn){
rd := bufio.NewReader(c)
var inbuf [64]byte
for{
n, err := rd.Read(inbuf[:])
if err != nil {
fmt.Println("Failed to receive msg from the server!")
break
}
fmt.Print(string(inbuf[:n]))
}
c.Close()
}
Upvotes: 0
Reputation: 41
I've modified your code to look like this. Although it seems to be working it is a bit primitive and lacks proper error handling.
server.go
package main
import (
"bufio"
"fmt"
"io"
"net"
"strings"
)
func (s *server) recvAndEcho(c io.ReadCloser) {
defer c.Close()
for {
netData, err := bufio.NewReader(c).ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
temp := strings.TrimSpace(string(netData))
fmt.Println(temp)
s.broadcastMsg(netData)
}
}
type server struct {
clients []io.Writer
}
func (s *server) addClient(c net.Conn) {
s.clients = append(s.clients, c)
}
func (s *server) broadcastMsg(msg string) {
for _, cl := range s.clients {
// Send the original msg back to the client
_, err := cl.Write([]byte(fmt.Sprintf("server replied: %s\n", msg)))
if err != nil {
fmt.Println("server: failed to write!")
}
}
}
func main() {
fmt.Println("Launching server...")
srv := &server{}
// listen on all interfaces
ln, _ := net.Listen("tcp", ":8081")
for {
// Listen for an incoming connection.
conn, err := ln.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
continue
}
srv.addClient(conn)
go srv.recvAndEcho(conn)
}
}
client.go
package main
import (
"bufio"
"fmt"
"io"
"net"
"os"
)
func recvLoop(r io.Reader) {
var inbuf [64]byte
for {
n, err := r.Read(inbuf[:])
if err != nil {
fmt.Println("Failed to receive msg from the server!")
break
}
fmt.Print(string(inbuf[:n]))
}
}
func main() {
// connect to this socket
conn, err := net.Dial("tcp", "127.0.0.1:8081")
if err != nil {
fmt.Println("Error accepting: ", err.Error())
return
}
sc := bufio.NewScanner(os.Stdin)
rd := bufio.NewReader(conn)
go recvLoop(rd)
for sc.Scan() {
if sc.Err() != nil {
fmt.Println("scanner error!")
}
txt := sc.Text()
// It is important to append "newline" here because you are
// using the "ReadString('\n')" method on the server side.
// Otherwise, the program would stuck at the "readstring"
// method.
b := []byte(txt + "\n")
_, err := conn.Write(b)
if err != nil {
fmt.Println("Failed to send data to the server!")
break
}
}
conn.Close()
}
Upvotes: 1