Golang中如何实现这个逻辑?
Golang中如何实现这个逻辑? 我有一个用Python编写的代理,其中包含一些逻辑,我想在我自己的Go工具中实现它,但我真的不知道该如何操作。
它通过套接字(标准输出)发送的数据被分割成小块,并在每个块之间设置延迟。
我有一个变量,它从一个列表中获取随机数:
....
listbytes = [87, 88, 89, 90]
....
我还有一个函数,它将数据(lst)分割成小字节块(n):
............
def chunks(lst, n):
"Yield successive chunks from lst, where n is a list of possible sizes"
i = 0
while i < len(lst):
k = min(random.choice(n), len(lst) - i)
yield lst[i:i + k]
i += k
.............
这两部分按以下方式执行:
...
# get the data
data = s.recv(BUFFER_SIZE)
if s == s_src:
d = LOCAL_DATA_HANDLER(data)
for chunk in chunks(d, listbytes):
#sleep 1.6 seconds before sending the next chunk of data
time.sleep(1.6)
#send the chunked data
s_dst.send(bytes(chunk) )
...
我该如何实现完全相同的逻辑?
func (nObj NetObject) RunClient(cmd string) {
// Try connection
for {
conn, err := net.Dial(nObj.Type, nObj.Service)
fmt.Print("connect")
// msg := "status"
if err != nil {
fmt.Println("fail")
}
if err == nil {
fmt.Println("ok")
// defer conn.Close()
defer conn.Close()
log.Println("Connected to", conn.RemoteAddr())
handleConn(conn, cmd)
//handleConn(conn, cmd)
fmt.Println("After handle")
}
fmt.Println("Before sleep")
time.Sleep(5 * time.Second)
}
}
// Manage connection for different behavior
func handleConn(conn net.Conn, binPath string) {
msg := "Status?\n"
if binPath != "" {
// Execute command and send Standard I/O net.Conn
cmd := exec.Command(binPath)
cmd.Stdin = conn
cmd.Stdout = conn
cmd.Stderr = conn
cmd.Run()
fmt.Println("Disconnected!?")
time.Sleep(5 * time.Second)
pippo, err2 := conn.Write([]byte(msg))
if err2 != nil {
fmt.Println(pippo)
}
} else {
// Copy Standard I/O in a net.Conn
go io.Copy(os.Stderr, conn)
go io.Copy(os.Stdout, conn)
io.Copy(conn, os.Stdin)
}
}
在Python中,实现起来很直接,而且效果很好。
该工具每次生成一个块时,都会从listbytes中随机选取一个数字。

我只是在寻找一位有耐心的高手(或者说是圣人,哈哈),他能提供一个代码示例,展示如何按照我的意愿工作。
我并不指望一开始就能让它运行起来,这几乎是不可能的,但我们都知道,通过一些错误,你迟早会找到解决方案(:
在这种情况下,我真的不知道从哪里开始,也不知道该怎么做(我是Go的新手)。 你能帮帮我吗?
更多关于Golang中如何实现这个逻辑?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
也许你指的是 data, _ := cmd.Output()?
更多关于Golang中如何实现这个逻辑?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我的猜测是,当你读取标准输出时,cmd 还没有执行,所以它的标准输出还是空的。也许你需要把 for-loop 放在 cmd.Run() 调用之后…
func main() {
fmt.Println("hello world")
}
感谢您的回答!
问题在于 io.Writer 不是一个字符串;所以我既不能获取它的长度,也不能对其进行切片。
我必须创建一个 bytes.Buffer:
buf := new(bytes.Buffer)
cmd.Stdout = buf
现在我需要将 *bytes.Buffer 转换为 []byte,这有点让人头疼,哈哈。
当客户端连接到服务器时,我无法获取标准输出……(这件事快把我逼疯了,哈哈) 对于我从服务器发送的任何输入(命令),我都收不到输出。 我到底遗漏了什么?
cmd := exec.Command(binPath)
cmd.Stdin = conn
// 原始代码----
// cmd.Stdout = conn
buf := new(bytes.Buffer)
cmd.Stdout = buf
for {
test := split(buf.Bytes(), 100)
last := make([]byte, len(test))
fmt.Println(last)
time.Sleep(1 * time.Second)
ok, err0 := conn.Write(last)
if err0 != nil {
fmt.Println(ok)
}
}
cmd.Stderr = conn
cmd.Run()
这是 split 函数:
func split(buf []byte, lim int) [][]byte {
var chunk []byte
chunks := make([][]byte, 0, len(buf)/lim+1)
for len(buf) >= lim {
chunk, buf = buf[:lim], buf[lim:]
chunks = append(chunks, chunk)
}
if len(buf) > 0 {
chunks = append(chunks, buf[:len(buf)])
}
return chunks
}
package main
import (
"math/rand"
"time"
)
// 定义可能的块大小列表
var listbytes = []int{87, 88, 89, 90}
// chunks 函数将数据分割成随机大小的块
func chunks(data []byte) <-chan []byte {
ch := make(chan []byte)
go func() {
defer close(ch)
i := 0
for i < len(data) {
// 从listbytes中随机选择一个块大小
chunkSize := listbytes[rand.Intn(len(listbytes))]
// 确保不超过剩余数据长度
if chunkSize > len(data)-i {
chunkSize = len(data) - i
}
// 发送数据块
ch <- data[i : i+chunkSize]
i += chunkSize
// 延迟1.6秒
time.Sleep(1600 * time.Millisecond)
}
}()
return ch
}
// 使用示例
func processData(data []byte, conn net.Conn) {
for chunk := range chunks(data) {
// 发送数据块
_, err := conn.Write(chunk)
if err != nil {
// 处理错误
break
}
}
}
// 在handleConn函数中的使用示例
func handleConn(conn net.Conn, binPath string) {
// ... 现有代码 ...
// 接收数据的示例
buffer := make([]byte, 4096)
for {
n, err := conn.Read(buffer)
if err != nil {
break
}
data := buffer[:n]
// 处理并发送分块数据
processData(data, conn)
}
// ... 现有代码 ...
}
// 如果需要更接近Python原语的实现,可以使用切片操作
func chunksExact(data []byte, sizes []int) [][]byte {
var result [][]byte
i := 0
for i < len(data) {
// 随机选择块大小
chunkSize := sizes[rand.Intn(len(sizes))]
// 调整块大小以适应剩余数据
if chunkSize > len(data)-i {
chunkSize = len(data) - i
}
// 添加数据块
result = append(result, data[i:i+chunkSize])
i += chunkSize
}
return result
}
// 带延迟的发送函数
func sendWithDelay(conn net.Conn, data []byte) {
chunks := chunksExact(data, listbytes)
for _, chunk := range chunks {
conn.Write(chunk)
time.Sleep(1600 * time.Millisecond)
}
}
// 初始化随机数种子(在main函数中调用一次)
func init() {
rand.Seed(time.Now().UnixNano())
}

