Networking 尝试在go中实现端口扫描程序
我最近开始学习围棋。唯一的原因是goroutine似乎只存在于这种语言中(我有java背景,老实说,我永远不会完全切换到go)。 我想实现一个简单的端口扫描程序,它可以查找给定网络范围内的每个http服务器(具有打开的端口80的主机)。我是这样做的:Networking 尝试在go中实现端口扫描程序,networking,go,goroutine,Networking,Go,Goroutine,我最近开始学习围棋。唯一的原因是goroutine似乎只存在于这种语言中(我有java背景,老实说,我永远不会完全切换到go)。 我想实现一个简单的端口扫描程序,它可以查找给定网络范围内的每个http服务器(具有打开的端口80的主机)。我是这样做的: package main import ( "net" "fmt" "regexp" "strconv" "time" ) // next two functions are shamelessly co
package main
import (
"net"
"fmt"
"regexp"
"strconv"
"time"
)
// next two functions are shamelessly copied from somewhere
func ip2long(ipstr string) (ip uint32) {
r := `^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})`
reg, err := regexp.Compile(r)
if err != nil {
return
}
ips := reg.FindStringSubmatch(ipstr)
if ips == nil {
return
}
ip1, _ := strconv.Atoi(ips[1])
ip2, _ := strconv.Atoi(ips[2])
ip3, _ := strconv.Atoi(ips[3])
ip4, _ := strconv.Atoi(ips[4])
if ip1 > 255 || ip2 > 255 || ip3 > 255 || ip4 > 255 {
return
}
ip += uint32(ip1 * 0x1000000)
ip += uint32(ip2 * 0x10000)
ip += uint32(ip3 * 0x100)
ip += uint32(ip4)
return
}
func long2ip(ip uint32) string {
return fmt.Sprintf("%d.%d.%d.%d", ip>>24, ip<<8>>24, ip<<16>>24, ip<<24>>24)
}
// the actual code
func main() {
seconds := 10 // timeout
fmt.Println(seconds) // just to see it
timeOut := time.Duration(seconds) * time.Second // time out to pass to the DialTimeout
can := make(chan int) // a chan
req := func (ip string){ // parallelized function to do requests
c, err := net.DialTimeout("tcp", ip+":80",timeOut) // connect to ip with given timeout
if err == nil { // if we're connected
fmt.Println(ip) // output the successful ip
c.Close() // close connection
}
can <- 0 // tell that we're done
}
startIp := ip2long("50.97.99.0") // starting ip
endIp := ip2long("50.97.102.0")
curIp := startIp // current ip
go func(){ // a demon function ran as goroutine which listens to the chan
count := 0 // how many ips we processed
looper: // label to break
for{
<- can // wait for some goroutine to finish
curIp++ // next ip
count++
go req(long2ip(curIp)) // start new goroutine
if (curIp > endIp) { // if we've walked through the range
fmt.Println("final")
break looper;
}
}
}()
numGoes := 100 // number of goroutines ran at one time
for i := 0; i < numGoes; i++{
can <- 0 // start 100 goroutines
}
// standard way to make the program hung
var input string
fmt.Scanln(&input)
}
主程序包
进口(
“净额”
“fmt”
“regexp”
“strconv”
“时间”
)
//接下来的两个函数不知羞耻地从某处复制而来
func ip2long(ipstr字符串)(ip uint32){
r:=`^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})`
reg,err:=regexp.Compile(r)
如果错误!=零{
返回
}
ips:=注册查找字符串子匹配(ipstr)
如果ips==nil{
返回
}
ip1,:=strconv.Atoi(ips[1])
ip2,:=strconv.Atoi(ips[2])
ip3,:=strconv.Atoi(ips[3])
ip4,:=strconv.Atoi(ips[4])
如果ip1>255 | | ip2>255 | | ip3>255 | | ip4>255{
返回
}
ip+=uint32(ip1*0x1000000)
ip+=uint32(ip2*0x10000)
ip+=uint32(ip3*0x100)
ip+=uint32(ip4)
返回
}
func long2ip(ip uint32)字符串{
返回fmt.Sprintf(“%d.%d.%d.%d”,ip>>24,ip24,ip24,ip24)
}
//实际代码
func main(){
秒:=10//超时
fmt.Println(秒)//只是想看看
超时:=time.Duration(秒)*time.Second//传递给拨号超时的超时时间
can:=make(chan int)//a chan
req:=func(ip字符串){//执行请求的并行化函数
c、 err:=net.DialTimeout(“tcp”,ip+“:80”,超时)//使用给定的超时连接到ip
如果err==nil{//如果我们是连通的
fmt.Println(ip)//输出成功的ip
c、 Close()//关闭连接
}
can这里有一个稍微修改过的版本,它更习惯于go
有更简短的方法来编写,但这可能更清楚
逻辑基本上是一样的。我刚刚运行了它,它工作得很好,打印出了它连接到的几个IP。这个版本还打印了它失败的原因,这更适合于故障排除
运行此版本时是否仍有问题?如果有,您会遇到什么错误
我的版本
主程序包
进口(
“fmt”
“净额”
“regexp”
“strconv”
“同步”
“时间”
)
//接下来的两个函数不知羞耻地从某处复制而来
func ip2long(ipstr字符串)(uint32,错误){
r:=`^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})`
reg,err:=regexp.Compile(r)
如果错误!=零{
返回0,错误
}
ips:=注册查找字符串子匹配(ipstr)
如果ips==nil{
返回0,fmt.Errorf(“无效ip地址”)
}
变量ip1、ip2、ip3、ip4 int
如果ip1,err=strconv.Atoi(ips[1]);err!=nil{
返回0,错误
}
如果ip2,err=strconv.Atoi(ips[2]);err!=nil{
返回0,错误
}
如果ip3,err=strconv.Atoi(ips[3]);err!=nil{
返回0,错误
}
如果ip4,err=strconv.Atoi(ips[4]);err!=nil{
返回0,错误
}
如果ip1>255 | | ip2>255 | | ip3>255 | | ip4>255{
返回0,fmt.Errorf(“无效ip地址”)
}
ip:=uint32(ip1*0x1000000)
ip+=uint32(ip2*0x10000)
ip+=uint32(ip3*0x100)
ip+=uint32(ip4)
返回ip,无
}
func long2ip(ip uint32)字符串{
返回fmt.Sprintf(“%d.%d.%d.%d”,ip>>24,ip24,ip24,ip24)
}
//实际代码
func main(){
超时时间:=10*time.Second//传递给拨号超时的超时时间
fmt.Println(“超时为:”,超时)
req:=func(ip字符串){//执行请求的并行化函数
c、 err:=net.DialTimeout(“tcp”,ip+“:80”,超时)//使用给定的超时连接到ip
如果err==nil{//如果我们是连通的
fmt.Println(ip)//输出成功的ip
c、 Close()//关闭连接
}否则{
fmt.Println(“错误为:”,err)
}
}
startIp,err:=ip2long(“50.97.99.0”)//起始ip
如果错误!=零{
fmt.Println(错误)
返回
}
endIp,err:=ip2long(“50.97.102.0”)
如果错误!=零{
fmt.Println(错误)
返回
}
var wg sync.WaitGroup//主例程的同步器,用于等待生成的工作进程
ips:=make(chan uint32)//用于馈送ip地址的通道
//产生100名工人
对于idx:=0;idx<100;idx++{
工作组.添加(1)
go func(){
对于ip:=范围ip{
req(long2ip(ip))//执行ip检查
}
wg.Done()
}()
}
//向工人发送ip地址以进行处理
对于curIp:=星尖;curIp
package main
import (
"fmt"
"net"
"regexp"
"strconv"
"sync"
"time"
)
// next two functions are shamelessly copied from somewhere
func ip2long(ipstr string) (uint32, error) {
r := `^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})`
reg, err := regexp.Compile(r)
if err != nil {
return 0, err
}
ips := reg.FindStringSubmatch(ipstr)
if ips == nil {
return 0, fmt.Errorf("Invalid ip address")
}
var ip1, ip2, ip3, ip4 int
if ip1, err = strconv.Atoi(ips[1]); err != nil {
return 0, err
}
if ip2, err = strconv.Atoi(ips[2]); err != nil {
return 0, err
}
if ip3, err = strconv.Atoi(ips[3]); err != nil {
return 0, err
}
if ip4, err = strconv.Atoi(ips[4]); err != nil {
return 0, err
}
if ip1 > 255 || ip2 > 255 || ip3 > 255 || ip4 > 255 {
return 0, fmt.Errorf("Invalid ip address")
}
ip := uint32(ip1 * 0x1000000)
ip += uint32(ip2 * 0x10000)
ip += uint32(ip3 * 0x100)
ip += uint32(ip4)
return ip, nil
}
func long2ip(ip uint32) string {
return fmt.Sprintf("%d.%d.%d.%d", ip>>24, ip<<8>>24, ip<<16>>24, ip<<24>>24)
}
// the actual code
func main() {
timeOut := 10 * time.Second // time out to pass to the DialTimeout
fmt.Println("Timeout is:", timeOut)
req := func(ip string) { // parallelized function to do requests
c, err := net.DialTimeout("tcp", ip+":80", timeOut) // connect to ip with given timeout
if err == nil { // if we're connected
fmt.Println(ip) // output the successful ip
c.Close() // close connection
} else {
fmt.Println("Error is:", err)
}
}
startIp, err := ip2long("50.97.99.0") // starting ip
if err != nil {
fmt.Println(err)
return
}
endIp, err := ip2long("50.97.102.0")
if err != nil {
fmt.Println(err)
return
}
var wg sync.WaitGroup // synchronizer for main routine to wait for spawned workers
ips := make(chan uint32) // channel to feed ip addrs
//spawn 100 workers
for idx := 0; idx < 100; idx++ {
wg.Add(1)
go func() {
for ip := range ips {
req(long2ip(ip)) // perform check of ip
}
wg.Done()
}()
}
// send ip addrs to workers to process
for curIp := startIp; curIp <= endIp; curIp++ {
ips <- curIp
}
close(ips) // signal goroutines to end
wg.Wait() //wait for all goroutines to complete
}