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
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)
}
}
}
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))
}
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)
}
}
}
}
}
}
}
}
}
}
}
}
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.
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)
}
}
}
}