Sockets 什么';在goroutine中使用套接字的正确方法是什么

Sockets 什么';在goroutine中使用套接字的正确方法是什么,sockets,go,concurrency,goroutine,Sockets,Go,Concurrency,Goroutine,我正在阅读Go lang中关于套接字的不同内容。它可以在2个Goroutine中用于读写而不需要任何并发控制吗 我正在显示下面的代码,但是我使用频道也失败了 我基本上创建了一个小应用程序来拦截某个应用程序的通信协议,我正在替换服务器上的一些字节,以防它击中我电脑中的客户端 为此,我有两个围棋程序: 一个从服务器读取套接字,替换一些字节并发送到客户端 另一个是从客户端读取套接字并发送到服务器 它可以很好地处理一些消息,然后崩溃。 这是我的代码和控制台输出: ***注意:python中的类似实现可以

我正在阅读Go lang中关于套接字的不同内容。它可以在2个Goroutine中用于读写而不需要任何并发控制吗

我正在显示下面的代码,但是我使用频道也失败了

我基本上创建了一个小应用程序来拦截某个应用程序的通信协议,我正在替换服务器上的一些字节,以防它击中我电脑中的客户端

为此,我有两个围棋程序:

一个从服务器读取套接字,替换一些字节并发送到客户端

另一个是从客户端读取套接字并发送到服务器

它可以很好地处理一些消息,然后崩溃。 这是我的代码和控制台输出:

***注意:python中的类似实现可以正常工作

    package main

    import (
        "fmt"
        "net"
        "sync"
        "log"
    )

    func main() {

    var wg sync.WaitGroup
    wg.Add(2)

    server := StartShard()
    client := StartClient()

    go func() {
        ShardToClient(client, server)
        wg.Done()
    }()

    go func() {
        ClientToShard(client, server)
        wg.Done()
    }()

    wg.Wait()

}

func StartClient() (net.Conn){

    servAddr := "server1.gamek.io:2593"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", servAddr)
    checkError(err)
    conn, err := net.DialTCP("tcp", nil, tcpAddr)
    checkError(err)

    return conn
}

func StartShard() (net.Conn){

    service := "localhost:2593"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
    checkError(err)
    listener, err := net.ListenTCP("tcp", tcpAddr)
    checkError(err)
    conn, err := listener.Accept()
    checkError(err)

    return conn
}


func ShardToClient( client net.Conn, server net.Conn  ){

    var buf = make([]byte, 1024)
    var bufRead int
    var err error

    for {
        bufRead, err = client.Read(buf)
        checkError(err)

        if bufRead > 0 {
            if buf[0] == 0x8C{
                fmt.Println("AVOIDING REDIRECTION ...")
                buf[1] = 127;
                buf[2] = 0;
                buf[3] = 0;
                buf[4] = 1;
            }
            fmt.Printf("ShardToClient(%d): %X\n", bufRead, buf[0:bufRead])
            bufRead, _ = server.Write(buf[0:bufRead])

        }
    }
}

func ClientToShard( client net.Conn, server net.Conn  ){

    var buf = make([]byte, 1024)
    var bufRead int
    var err error

    for {
        bufRead, err = server.Read(buf)
        checkError(err)

        if bufRead > 0 {
            fmt.Printf("ClientToShard(%d): %X\n", bufRead, buf[0:bufRead])
            bufRead, err = client.Write(buf[0:bufRead])
            checkError(err)
        }
    }

}

func checkError(err error) {
    if err != nil {
        log.Fatal("fatal: %s", err)
    }
}
输出:

ClientToShard(66):0E00A8C0806761627000000073776F720000000000FF

ShardToClient(3):BD0003

ClientToShard(11):BD000B352E302E392E3000

ShardToClient(46):

A8002EF00015468652046690D0F723

客户托沙德(3):A00001

正在避免重定向

ShardToClient(11):8C7F0000010A214C8D6573

2019/01/12 14:32:45致命:EOF

报告说:

多个goroutine可以同时调用Conn上的方法

因此,我怀疑这不是问题本身,而是您的代码中有一个bug


在不使用shard和客户端等设置env的情况下调试代码是很困难的,但我只想指出,并发访问
Conn
不是问题所在。尝试引导客户端读取更多信息-是否使用EOF读取任何数据?

应用程序通过调用
log.Fatal
处理网络操作中的所有错误。致命函数退出该进程

日志行

2019/01/12 14:32:45 FATAL: EOF
指示对等方关闭了网络连接。应用程序通过退出来处理此错误

应用程序应该通过清理任何资源和退出goroutine来处理网络错误。例如:

func ClientToShard( client net.Conn, server net.Conn  ){
    defer client.Close() // close network connections on return from this function
    defer server.Close()

    var buf = make([]byte, 1024)
    var bufRead int
    var err error

    for {
        bufRead, err = server.Read(buf)
        if err != nil {
            return
        }

        if bufRead > 0 {
            fmt.Printf("ClientToShard(%d): %X\n", bufRead, buf[0:bufRead])
            bufRead, err = client.Write(buf[0:bufRead])
            if err != nil {
                return
            }
        }
    }

}
对ShardToClient进行类似的更改

附加注释:将
ClientToShard
的核心替换为调用