在Go协程中追加切片

huangapple go评论92阅读模式
英文:

Append slice in go routine

问题

我正在尝试自学Go语言。我编写了一个简单的客户端/服务器应用程序,其中包含一些加密和非常简单的数据包结构。

我有一个用于监听并向每个连接的客户端发送数据的Go协程。在发送数据给每个客户端的函数中,我将一条消息附加到头部,但它表现出一些奇怪的行为。

func ClientSender(client *Client) {
	for {
		input := <-client.Outgoing //TODO add cleanup quit bool
		for _, clientz := range RoomList[client.Room].Clients { //TODO rename to client connections = ClientList
			temp := input
			dbgMsg.Printf("RAW SENDER: % x", input)
			dbgMsg.Printf("INPUT END1: % x", input)
			dbgMsg.Printf("AES KEY % x\n", clientz.AES_Key)
			dbgMsg.Printf("INPUT END2: % x", input)
			dbgMsg.Printf("pre ecnryp: % x\n", input[30:])
			dbgMsg.Printf("INPUT END3: % x", input)
			encPayload := input[30:]
			dbgMsg.Printf("INPUT END4: % x", input)
			header := input[:30]
			dbgMsg.Printf("INPUT END5: % x", input)
			e,_ := barrenoid.Encrypt(clientz.AES_Key, encPayload)
			dbgMsg.Printf("INPUT END6: % x", input)
			dbgMsg.Printf("header: % x\n", input[:30])
			dbgMsg.Printf("payload: % x\n", input[30:])
			dbgMsg.Printf("encrypt: % x\n", e)
			dbgMsg.Printf("TEMP: % x\n", temp)
			asdf := append(header, e...)
			dbgMsg.Printf("SENDING: % x", asdf)
			//_, err := clientz.Conn.Write(payload)
			//chkError(err)
			input = temp
			dbgMsg.Printf("INPUT END7: % x", input)
		}
	}
}

"input"的值发生了变化,我无法弄清楚为什么。以下是上述代码的输出:

INFO: 2016/02/22 10:47:38 RAW SENDER: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 INPUT END1: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 AES KEY 06 89 c9 d7 ad ec 4a d0 33 bf fa ab 6e 05 cd 51 87 8b f0 ad 60 a8 36 47 ca 8f 7a f8 b8 6f 1c ce
INFO: 2016/02/22 10:47:38 INPUT END2: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 pre ecnryp: 0a
INFO: 2016/02/22 10:47:38 INPUT END3: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 INPUT END4: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 INPUT END5: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 INPUT END6: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 header: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00
INFO: 2016/02/22 10:47:38 payload: 0a
INFO: 2016/02/22 10:47:38 encrypt: ***c8*** 7e ff f9 f5 c3 ce 1e 1d 44 91 b7 fb 09 5d e0 7e
INFO: 2016/02/22 10:47:38 TEMP: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO: 2016/02/22 10:47:38 SENDING: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 c8 7e ff f9 f5 c3 ce 1e 1d 44 91 b7 fb 09 5d e0 7e
INFO: 2016/02/22 10:47:38 INPUT END7: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 ***c8***

我无法弄清楚为什么包含"INPUT END7"的行与"input"的值不相等。

最后一个字节始终等于"encrypted"输出的第一个字节...

以下是将切片发送到通道的代码:

```go
func ClientReader(client *Client) {
	//Main Read loop
	for {
		bytesRead, buffer := client.Read()

		if bytesRead < HEADERSIZE {
			//client.Outgoing <- protocolPacker(0x0D, 0xAE, []byte(""), []byte("Minimum header not recieved."))
			client.Close()
			break // Connection to host is broken
		}

		//dbgMsg.Printf("RAW RECIEVED % x", buffer)
		cmdBit, encryptionByte, ts, payload := protocolParser(buffer)
		dbgMsg.Printf("CMDBIT: % x, ENCBIT: % x, TS: % d, PAYLOAD: % x", cmdBit, encryptionByte, ts, payload)


		if encryptionByte == 0xAE {
			payload, _ = barrenoid.Decrypt(client.AES_Key, payload)
			dbgMsg.Printf("Decrypted payload % x\n", payload)
		} else if encryptionByte == 0x00 {
			// no need to decrypt
		} else {
			//bad packet reject
		}

		if cmdBit == 0x0D{
			//payload, _ = barrenoid.Encrypt(client.AES_Key, payload)
			client.Outgoing <- protocolPacker(0x0D, 0xAE, []byte(client.Name), payload)
		} else if cmdBit == 0x1C {
			client.Name = string(payload)
		} else {
			//bad packet reject
			//client.Outgoing <- protocolPacker(0x0D, 0xAE, []byte(client.Name), []byte("Unknown command bit."))
		}
	}
}

希望这能帮助你解决问题。

英文:

I am trying to teach myself Go. I have written a simple client / server app that has some encryption and very simple packet structure.

I have a go routine for listening and then sending data to each client connected. In my function that sends data to each client i'm appending a message to a header but its doing some strange behavior.

func ClientSender(client *Client) {
for {
	input := &lt;-client.Outgoing                             //TODO add cleanup quit bool
	for _, clientz := range RoomList[client.Room].Clients { //TODO rename to client connections = ClientList
		temp := input
		dbgMsg.Printf(&quot;RAW SENDER: % x&quot;, input)
		dbgMsg.Printf(&quot;INPUT END1: % x&quot;, input)
		dbgMsg.Printf(&quot;AES KEY % x\n&quot;, clientz.AES_Key)
		dbgMsg.Printf(&quot;INPUT END2: % x&quot;, input)
		dbgMsg.Printf(&quot;pre ecnryp: % x\n&quot;, input[30:])
		dbgMsg.Printf(&quot;INPUT END3: % x&quot;, input)
		encPayload := input[30:]
		dbgMsg.Printf(&quot;INPUT END4: % x&quot;, input)
		header := input[:30]
		dbgMsg.Printf(&quot;INPUT END5: % x&quot;, input)
		e,_ := barrenoid.Encrypt(clientz.AES_Key, encPayload)
		dbgMsg.Printf(&quot;INPUT END6: % x&quot;, input)
		dbgMsg.Printf(&quot;header: % x\n&quot;, input[:30])
		dbgMsg.Printf(&quot;payload: % x\n&quot;, input[30:])
		dbgMsg.Printf(&quot;encrypt: % x\n&quot;, e)
		dbgMsg.Printf(&quot;TEMP: % x\n&quot;, temp)
		asdf := append(header, e...)
		dbgMsg.Printf(&quot;SENDING: % x&quot;, asdf)
		//_, err := clientz.Conn.Write(payload)
		//chkError(err)
		input = temp
		dbgMsg.Printf(&quot;INPUT END7: % x&quot;, input)
	}
}
}

The value of "input" get changed and i cant figure out why. here is output from the above code:

INFO:	2016/02/22 10:47:38 RAW SENDER: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a

INFO:	2016/02/22 10:47:38 INPUT END1: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO:	2016/02/22 10:47:38 AES KEY 06 89 c9 d7 ad ec 4a d0 33 bf fa ab 6e 05 cd 51 87 8b f0 ad 60 a8 36 47 ca 8f 7a f8 b8 6f 1c ce
INFO:	2016/02/22 10:47:38 INPUT END2: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO:	2016/02/22 10:47:38 pre ecnryp: 0a
INFO:	2016/02/22 10:47:38 INPUT END3: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO:	2016/02/22 10:47:38 INPUT END4: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO:	2016/02/22 10:47:38 INPUT END5: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO:	2016/02/22 10:47:38 INPUT END6: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO:	2016/02/22 10:47:38 header: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00
INFO:	2016/02/22 10:47:38 payload: 0a
INFO:	2016/02/22 10:47:38 encrypt: ***c8*** 7e ff f9 f5 c3 ce 1e 1d 44 91 b7 fb 09 5d e0 7e
INFO:	2016/02/22 10:47:38 TEMP: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 0a
INFO:	2016/02/22 10:47:38 SENDING: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 c8 7e ff f9 f5 c3 ce 1e 1d 44 91 b7 fb 09 5d e0 7e
INFO:   2016/02/22 10:47:38 INPUT END7: 0d ae 00 00 00 00 56 cb 57 ca 41 6e 6f 6e 79 6d 6f 75 73 00 00 00 00 00 00 00 00 00 00 00 ***c8***

I cant figure out why the line containing "INPUT END7" is not equal the the "input" value.

The last byte is ALWAYS equal to the first byte in "encrypted"output...

Here is code that sends slice to channel:

func ClientReader(client *Client) {
//Main Read loop
for {
	bytesRead, buffer := client.Read()

	if bytesRead &lt; HEADERSIZE {
		//client.Outgoing &lt;- protocolPacker(0x0D, 0xAE, []byte(&quot;&quot;), []byte(&quot;Minimum header not recieved.&quot;))
		client.Close()
		break // Connection to host is broken
	}

	//dbgMsg.Printf(&quot;RAW RECIEVED % x&quot;, buffer)
	cmdBit, encryptionByte, ts, payload := protocolParser(buffer)
	dbgMsg.Printf(&quot;CMDBIT: % x, ENCBIT: % x, TS: % d, PAYLOAD: % x&quot;, cmdBit, encryptionByte, ts, payload)


	if encryptionByte == 0xAE {
		payload, _ = barrenoid.Decrypt(client.AES_Key, payload)
		dbgMsg.Printf(&quot;Decrypted payload % x\n&quot;, payload)
	} else if encryptionByte == 0x00 {
		// no need to decrypt
	} else {
		//bad packet reject
	}

	if cmdBit == 0x0D{
		//payload, _ = barrenoid.Encrypt(client.AES_Key, payload)
		client.Outgoing &lt;- protocolPacker(0x0D, 0xAE, []byte(client.Name), payload)
	} else if cmdBit == 0x1C {
		client.Name = string(payload)
	} else {
		//bad packet reject
		//client.Outgoing &lt;- protocolPacker(0x0D, 0xAE, []byte(client.Name), []byte(&quot;Unknown command bit.&quot;))
	}
}

答案1

得分: 2

slices中的tempinput共享相同的底层数组。通过一个切片进行的修改可以通过另一个切片看到。包含“INPUT END7”的行与包含“INPUT END1”的行不同,因为在这一行中修改了切片的底层数组:

asdf := append(header, e...)

您可以使用以下代码行复制底层数组:

temp := append([]byte(nil), input...)
英文:

The slices temp and input share the same backing array. Modifications through one slice are visible through the other. The line containing "INPUT END7" is not the same as the line with "INPUT END1" because the backing array of the slices is modified on this line:

asdf := append(header, e...)

You can copy the backing array using this line of code:

temp := append([]byte(nil), input...)

huangapple
  • 本文由 发表于 2016年2月23日 03:01:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/35561721.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定