Go - net.LookupAddr doesn't execute - network-programming

Before I added the feature to accept a input address all works fine.
After splitting of the IP-Address into 3 segments and surrender it to the getHostName function, the program skips "all/inclusive of the function" after the call of the function net.LookupAddr(ip).
package main
import (
"fmt"
"net"
"strconv"
"strings"
)
func getHostName(h chan string, ipAdresse string, n int) {
ip := ipAdresse + strconv.Itoa(n)
addr, ok := net.LookupAddr(ip)
fmt.Println(ok)
if ok == nil {
h <- ip + " - " + addr[0]
} else {
fmt.Println(ok)
}
}
func printer(n chan string) {
msg := <-n
fmt.Println(msg)
}
func main() {
fmt.Println("Please enter your local IP-Adresse e.g 192.168.1.1")
var ipAdresse_user string
fmt.Scanln(&ipAdresse_user)
ipsegment := strings.SplitAfter(ipAdresse_user, ".")
ipadresse_3 := ipsegment[0] + ipsegment[1] + ipsegment[2]
host := make(chan string)
for i := 0; i < 55; i++ {
go getHostName(host, ipadresse_3, i)
go printer(host)
}
fmt.Println("Finish - Network Scan")
}

My mistake i have to block the main function with e.g Scanln. Without it the program terminates before the goroutines can be executed.

Related

Is there any way to run my containers periodically?

I'm trying to write a program that from the main "server", calls for 2 "agents" that each one of them creates containers. Each container should run periodically and every 10 seconds print the time. The create command is taken from the Std.in as <command> <PATH>.
For example, I pass 4 containers to create, so agent1 creates 2, and agent2 creates 2.
My problem is that when I run this program I only see the second container from agent1 when I type docker ps I get only mycontainer2.
And only after I stop/remove mycontainer2, only then agent2 creates mycontainer4. (mycontainer1 and mycontainer3 wasn't created at all).
Probably the way I created them was wrong. Is there any way I can create all of them and let them run separately?
Main "server":
package main
import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
"bufio"
"os"
"bytes"
"os/exec"
"strings"
"strconv"
)
type conf struct {
Name string `yaml:"Name"`
Amount int `yaml:"Amount"`
Image string `yaml:"Image"`
}
func (c *conf) getConf() *conf {
yamlFile, err := ioutil.ReadFile("conf.yaml")
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
log.Fatalf("Unmarshal: %v", err)
}
return c
}
func isError(err error) bool {
if err != nil {
fmt.Println(err.Error())
}
return (err != nil)
}
func showEnvStatus() {
cmd := exec.Command("echo", "Hello from ShowEnv")
// cmd.Stdin = strings.NewReader("some input")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The out put is: %q\n", out.String())
return
}
func createAgents(c conf){
var workload = c.Amount/2
var rightBroderAgent1 = strconv.Itoa(workload)
var leftBorderAgent2 = strconv.Itoa(c.Amount- workload + 1)
//invoke agent1. Args are the range of the containers numbers for names. (0 : workload)
cmd1 := exec.Command("./agent","1", rightBroderAgent1, c.Name, c.Image)
var out bytes.Buffer
cmd1.Stdout = &out
err1 := cmd1.Run()
if err1 != nil {
fmt.Println(err1)
}
fmt.Println("%q\n",out.String())
//invoke agent2. Args are the range of the containers numbers for names.(workload+1 : Amount)
cmd2 := exec.Command("./agent",leftBorderAgent2, strconv.Itoa(c.Amount),c.Name, c.Image)
err2 := cmd2.Run()
if err2 != nil {
log.Fatal(err2)
}
return
}
func parseCommand(text string) ([]string){
res := strings.Split(text, " ")
return res
}
func main() {
i := 0
for i < 1{
var args []string
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n')
args = parseCommand(text)
switch args[0] {
case "create":
var c conf
c.getConf()
createAgents(c)
default:
fmt.Println("Unknown command, try again")
}
}
}
############################# Agent file ##################
func main(){
// Args[] structure : {FILE, left border, right border, container's name, image}
left,_ := strconv.Atoi(os.Args[1])
right,_ := strconv.Atoi(os.Args[2])
for i := left; i <= right; i++ {
fmt.Println(left, right)
var name string = os.Args[3] + strconv.Itoa(i+1)
cmd1 := exec.Command("docker", "run", "--name", name, "-it", "-d", os.Args[4])
cmd2 := exec.Command("docker", "cp", "showtime" ,name + ":/showtime")
cmd3 := exec.Command("docker", "exec" ,name , "./showtime")
// cmds := []*exec.Cmd{cmd1,cmd2,cmd3}
err1 := cmd1.Run()
if err1 != nil {
fmt.Println(err1)
os.Exit(2)
}
err2 := cmd2.Run()
if err2 != nil {
fmt.Println(err2)
os.Exit(2)
}
err3 := cmd3.Run()
if err3 != nil {
fmt.Println(err3)
os.Exit(2)
}
}
}

How to stream video capture to web

I've the below code that read the cam and display it in GUI window, I want to push the same thing to my server at url localhost:8080/cam, how can I do this?
package main
import (
"gocv.io/x/gocv"
)
func main() {
webcam, _ := gocv.VideoCaptureDevice(0)
defer webcam.Close() // Close the cam once execution completed
window := gocv.NewWindow("Hello")
defer window.Close() // Close the GUI once execution completed, though it is done automatically
img := gocv.NewMat()
defer img.Close() // Close the img once execution completed
for {
webcam.Read(&img)
window.IMShow(img)
// Want to do streaming here to localhost:8080/cam
if window.WaitKey(1) == 27 { // 27 => Esc
break
}
}
}
I found the solution with this package, a fork of this
package mjpeg
import (
"fmt"
"log"
"net/http"
"sync"
"time"
)
// Stream represents a single video feed.
type Stream struct {
m map[chan []byte]bool
frame []byte
lock sync.Mutex
FrameInterval time.Duration
}
const boundaryWord = "MJPEGBOUNDARY"
const headerf = "\r\n" +
"--" + boundaryWord + "\r\n" +
"Content-Type: image/jpeg\r\n" +
"Content-Length: %d\r\n" +
"X-Timestamp: 0.000000\r\n" +
"\r\n"
// ServeHTTP responds to HTTP requests with the MJPEG stream, implementing the http.Handler interface.
func (s *Stream) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Println("Stream:", r.RemoteAddr, "connected")
w.Header().Add("Content-Type", "multipart/x-mixed-replace;boundary="+boundaryWord)
c := make(chan []byte)
s.lock.Lock()
s.m[c] = true
s.lock.Unlock()
for {
time.Sleep(s.FrameInterval)
b := <-c
_, err := w.Write(b)
if err != nil {
break
}
}
s.lock.Lock()
delete(s.m, c)
s.lock.Unlock()
log.Println("Stream:", r.RemoteAddr, "disconnected")
}
// UpdateJPEG pushes a new JPEG frame onto the clients.
func (s *Stream) UpdateJPEG(jpeg []byte) {
header := fmt.Sprintf(headerf, len(jpeg))
if len(s.frame) < len(jpeg)+len(header) {
s.frame = make([]byte, (len(jpeg)+len(header))*2)
}
copy(s.frame, header)
copy(s.frame[len(header):], jpeg)
s.lock.Lock()
for c := range s.m {
// Select to skip streams which are sleeping to drop frames.
// This might need more thought.
select {
case c <- s.frame:
default:
}
}
s.lock.Unlock()
}
// NewStream initializes and returns a new Stream.
func NewStream() *Stream {
return &Stream{
m: make(map[chan []byte]bool),
frame: make([]byte, len(headerf)),
FrameInterval: 50 * time.Millisecond,
}
}
Any my running code is:
package main
import (
"fmt"
"log"
"net/http"
"github.com/hybridgroup/mjpeg"
_ "github.com/hybridgroup/mjpeg"
"gocv.io/x/gocv"
)
func main() {
deviceID := 0
webcam, err := gocv.OpenVideoCapture(deviceID)
if err != nil {
fmt.Printf("Error opening video capture device: %v\n", deviceID)
return
}
// create the mjpeg stream
stream := mjpeg.NewStream()
// start capturing
go func(webcam *gocv.VideoCapture, stream *mjpeg.Stream) {
defer webcam.Close()
window := gocv.NewWindow("Capture Window")
defer window.Close()
img := gocv.NewMat()
defer img.Close()
fmt.Printf("Start reading device: %v\n", deviceID)
for {
if ok := webcam.Read(&img); !ok {
fmt.Printf("Device closed: %v\n", deviceID)
return
}
if img.Empty() {
continue
}
buf, _ := gocv.IMEncode(".jpg", img)
stream.UpdateJPEG(buf)
window.IMShow(img)
if window.WaitKey(1) == 27 { // 27 => Esc
break
}
}
}(webcam, stream)
http.Handle("/", stream)
log.Fatal(http.ListenAndServe(":8080", nil))
}

How to parse the statements in a method or function with Go

I would like to parse go code, and more especially the content of a function.
So far it's pretty easy to get the function declaration with the parser.ParseFile function.
package main
import (
"fmt"
"go/parser"
"go/token"
"go/ast"
"log"
)
var code = []byte(`
package main
import (
"fmt"
)
func GetFoo() {
test := foo()
fmt.Println(test)
}
func foo() int {
return 0
}
`)
func main() {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", code, parser.ParseComments)
if err != nil {
log.Fatal(err)
}
for _, decl := range f.Decls {
switch t := decl.(type) {
// That's a func decl !
case *ast.FuncDecl:
fmt.Printf("Function name: %v\n", t.Name)
// Now I would like to access to the test var and get its type
// Must be int, because foo() returns an int
}
}
}
Now I would like to access to the test var and get its type, but I am a little bit lost. I have seen the decl.Body.List to iterate over the statements but I can get that my test var is an int
Thank you for your precious help !
https://play.golang.org/p/Y8uwM-CDWy
Thanks to JimB and his hint about go/types, here's how I could get the signature of my method
package main
import (
"fmt"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
)
var code = []byte(`
package main
import (
"fmt"
)
func GetFoo() {
test := foo()
fmt.Println(test)
}
func foo() int {
return 0
}
`)
func main() {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", code, parser.ParseComments)
if err != nil {
log.Fatal(err)
}
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("cmd", fset, []*ast.File{f}, nil)
scope := pkg.Scope()
for _, decl := range f.Decls {
switch t := decl.(type) {
// That's a func decl !
case *ast.FuncDecl:
for _, s := range t.Body.List {
switch as := s.(type) {
case *ast.AssignStmt:
for _, l := range as.Rhs {
switch rh := l.(type) {
case *ast.CallExpr:
if i, ok := rh.Fun.(*ast.Ident); ok {
ft := scope.Lookup(i.Name)
if ft != nil {
if ftype, ok := ft.(*types.Func); ok {
f := ftype.Type()
if sig, ok := f.(*types.Signature); ok {
// get the returned elements
r := sig.Results()
for i := 0; i < r.Len(); i++ {
v := r.At(i)
varTpe := v.Type()
fmt.Println(varTpe)
}
}
}
}
}
}
}
}
}
}
}
}

go/types finding if struct implements interface

OK so looking at using go/types, go/parser... an so forth to generate some code; but need to identify all structs that implement a specific interface which I have figured out, however, if the struct definition on the struct function it does not match using types.Implements.
OK the code examples:
Getting the interface
package ifacepkg
const interfacePkg = `package ifacepkg
type MyInterface interface {
MyFunction() error
}
`
func getIface() *types.Interface {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "iface.go", interfacePkg, 0)
if err != nil {
panic(err)
}
config := &types.Config{
Error: func(e error) {
fmt.Println(e)
},
Importer: importer.Default(),
}
info := types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
}
pkg, e := config.Check("genval", fset, []*ast.File{f}, &info)
if e != nil {
fmt.Println(e)
}
return pkg.Scope().Lookup("MyInterface").Type().Underlying().(*types.Interface)
}
Test File
package test
import "ifacepkg"
// User struct
type User struct {
FirstName string
LastName string
}
func (u User) MyFunction() error {
return nil
}
var _ ifacepkg.MyInterface = &User{}
Loading Test File & trying to see if User implements MyInterface
fset := token.NewFileSet()
pkgs, e := parser.ParseDir(fset, "./test", nil, 0)
if e != nil {
log.Fatal(e)
// return
}
var astf []*ast.File
for _, pkg := range pkgs {
fmt.Printf("package %v\n", pkg.Name)
for fn, f := range pkg.Files {
fmt.Printf("file %v\n", fn)
astf = append(astf, f)
}
}
config := &types.Config{
Error: func(e error) {
fmt.Println(e)
},
Importer: importer.Default(),
}
info := types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
}
pkg, e := config.Check(path, fset, astf, &info)
if e != nil {
fmt.Println(e)
}
vIface := getIface()
fmt.Println(vIface)
scope := pkg.Scope()
for _, name := range scope.Names() {
obj := scope.Lookup(name)
_, ok := obj.Type().Underlying().(*types.Struct)
imp := types.Implements(obj.Type(), vIface)
fmt.Println(obj.Name(), ok, imp)
}
OK so fmt.Println(obj.Name(), ok, imp) prints User true true all good! however if I change the source file function from
func (u User) MyFunction() error {
to
func (u *User) MyFunction() error {
it now prints User true false
so the function types.Implements is reporting that User does not implement MyInterface, which is not true.
So my question is: Is there an issue with the type.Implements method or is there something I have to do to my object prior to calling that function.
Answer
ok to solve my own issue changing final portion of code to
scope := pkg.Scope()
for _, name := range scope.Names() {
obj := scope.Lookup(name)
_, ok := obj.Type().Underlying().(*types.Struct)
ptr := types.NewPointer(obj.Type())
imp := types.Implements(ptr.Underlying(), vIface)
fmt.Println(obj.Name(), ok, imp)
}
which works with both Pointer and non-pointer recievers
What your compiler is telling you is true. *Type != Type in Go. If you want *User to implement your interface then the methods receiver has to be *User and if you want it to be User then it needs to be User. I don't really know how else to explain it... Go's type system is strict and those aren't the same. You can see this more practically if you have (u *User) MyFunction() defined for the pointer type do ptr := &MyUser then check if MyUser and ptr implement the interface, ptr will, MyUser will not.

How to parse a method declaration?

I'm trying to parse a method declaration. Basically I need to get the syntax node of the receiver base type (type hello) and the return types (notype and error). The ast package seems straightforward but for some reason I don't get the data I need (i.e. the fields are reported nil).
The only useful data seems provided only in Object -> Decl field which is of type interface{} so I don't think I can serialize it.
Any help would be appreciated. Code below:
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
// src is the input for which we want to inspect the AST.
src := `
package mypack
// type hello is a cool type
type hello string
// type notype is not that cool
type notype int
// func printme is like nothing else.
func (x *hello)printme(s string)(notype, error){
return 0, nil
}
`
// Create the AST by parsing src.
fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(fset, "src.go", src, 0)
if err != nil {
panic(err)
}
// Inspect the AST and find our function
var mf ast.FuncDecl
ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.FuncDecl:
mf = *x
}
return true
})
if mf.Recv != nil {
fmt.Printf("\n receivers:")
for _, v := range mf.Recv.List {
fmt.Printf(",tag %v", v.Tag)
for _, xv := range v.Names {
fmt.Printf("name %v, decl %v, data %v, type %v",
xv.Name, xv.Obj.Decl, xv.Obj.Data, xv.Obj.Type)
}
}
}
}
Playground
To get the type you need to look at the Type attribute which could be an ast.StarExpr or an ast.Ident.
Here take a look at this :
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
// src is the input for which we want to inspect the AST.
src := `
package mypack
// type hello is a cool type
type hello string
// type notype is not that cool
type notype int
// printme is like nothing else.
func (x *hello)printme(s string)(notype, error){
return 0, nil
}
`
// Create the AST by parsing src.
fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(fset, "src.go", src, 0)
if err != nil {
panic(err)
}
// Inspect the AST and find our function
var mf ast.FuncDecl
ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.FuncDecl:
mf = *x
}
return true
})
if mf.Recv != nil {
for _, v := range mf.Recv.List {
fmt.Print("recv type : ")
switch xv := v.Type.(type) {
case *ast.StarExpr:
if si, ok := xv.X.(*ast.Ident); ok {
fmt.Println(si.Name)
}
case *ast.Ident:
fmt.Println(xv.Name)
}
}
}
}

Resources