我正在阅读有关Go lang中套接字的不同内容。可以在没有任何并发控制的情况下在2个goroutine中使用它进行读写吗?
我在显示下面的代码,但我也无法使用频道。
我基本上创建了一个小应用程序来拦截某个应用程序的通信协议,并且在服务器上的一些字节到达我的PC客户端之前,我正在从服务器中替换一些字节。
为此,我有2个go例程:
从服务器读取套接字,替换一些字节并发送给客户端。
另一个是从客户端读取套接字并发送到服务器。
对于一些消息工作正常,然后崩溃。 这是我的代码和控制台输出:
***注意:类似的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):0E00A8C08067616270000000073776F720000000FF
ShardToClient(3):BD0003
ClientToShard(11):BD000B352E302E392E3000
ShardToClient(46):
A8002EFF000100015468652046690D0F723
ClientToShard(3):A00001
避免重定向...
ShardToClient(11):8C7F0000010A214C8D6573
2019/01/12 14:32:45致命:EOF
答案 0 :(得分:1)
应用程序通过调用log.Fatal
处理来自网络操作的所有错误。 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进行类似的更改。
奖金评论:用对io.Copy的调用替换ClientToShard
的核心。
答案 1 :(得分:0)
多个goroutine可以同时在Conn上调用方法。
所以我怀疑这不是问题本身,而是您的代码中有一个错误。
不使用分片和客户端等设置环境就很难调试代码,但是我只想指出并发访问Conn
并不是问题。尝试让客户端了解更多信息-EOF是否读取了任何数据?