我正在尝试自学围棋。我写了一个简单的客户端/服务器应用程序,它有一些加密和非常简单的数据包结构。
我有一个 go 例程用于监听然后将数据发送到每个连接的客户端。在我向每个客户端发送数据的函数中,我将一条消息附加到 header ,但它做了一些奇怪的行为。
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)
}
}
}
“输入”的值发生了变化,我不知道为什么。这是上面代码的输出:
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”的行不等于“输入”值。
最后一个字节总是等于“加密”输出中的第一个字节...
这是将 slice 发送到 channel 的代码:
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."))
}
}
最佳答案
slice temp 和 input 共享相同的后备数组。通过一个 slice 的修改通过另一个 slice 可见。包含“INPUT END7”的行与包含“INPUT END1”的行不同,因为在这一行修改了 slice 的支持数组:
asdf := append(header, e...)
您可以使用这行代码复制支持数组:
temp := append([]byte(nil), input...)
关于go - 在 go routine 中追加 slice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35561721/
查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用
在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol
在我看来,以下行为就像assign方法正在按值处理visited,而append方法将其视为引用:classMyClassdefassign(visited)visited+=["A"]enddefappend(visited)visited[]instance.append(visited)visited#=>["A"]有人可以解释这种行为吗?这不是关于Ruby是否支持按引用传递或按值传递的问题,而是关于下面提供的示例,以及为什么两个据称执行相同操作的方法表现出不同行为的问题。 最佳答案 您在第一个方法中重新定义了局部变量。这是一
自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例
我不明白为什么在Ruby中,Array#slice和Array#slice!的行为与Array#sort和Array#sort!(一个返回新数组的结果,另一个处理当前对象)。使用sort第一个(没有爆炸),返回当前数组的排序副本,并且sort!对当前数组进行排序。slice,返回指定范围的数组,slice!从当前对象删除指定范围。Array#slice!的行为为何如此,而不是使当前对象成为具有指定范围的数组?例子:a=[0,1,2,3,4,5,6,7,8,9]b=a.slice(2,2)puts"slice:"puts"a="+a.inspectputs"b="+b.inspectb=
Scala有Rubys的版本吗each_slice来自Array类? 最佳答案 Scala2.8有grouped将数据分成大小为n的block(可用于实现each_slice功能):scala>vala=Array(1,2,3,4,5,6)a:Array[Int]=Array(1,2,3,4,5,6)scala>a.grouped(2).foreach(i=>println(i.reduceLeft(_+_)))3711据我所知,在2.7.x中没有任何东西可以开箱即用,但是从take(n)和drop(n)来自RandomAccess
这个问题在这里已经有了答案:HowdoIcreatemultiplesubmitbuttonsforthesameforminRails?(7个答案)关闭9年前。所以..'save'%>'library'%>然后在我的Controller中:with_actiondo|a|a.savedoenda.librarydoendend问题是只有一个操作被调用...两个submit_tags调用相同的操作...知道为什么吗?或者我如何获得两个按钮以将表单提交给两种不同的方法?
这个问题在这里已经有了答案:Rubyarrayaccess2consecutive(chained)elementsatatime(4个答案)关闭3年前。给定这个Ruby数组:[1,2,3,4,5]像这样迭代它的最简单方法是什么?[[1,2],[2,3],[3,4],[4,5]]还是这个?[[1,2,3],[2,3,4],[3,4,5]]
我只是想在此字符串的末尾添加一个“/”。执行此操作的最佳方法是什么?>>params[:id]"shirts"我想制作params[:id]=="shirts/"。如何在该字符串的末尾添加/? 最佳答案 最简单的:params[:id]=params[:id]+'/'或params[:id]+='/'莫尔幻想:params[:id]另一种方法:params[:id].concat'/'如果你真的出于某种奇怪的原因坚持使用gsub:params[:id].gsub!/$/,'/' 关于ru
IV.SYSTEMIMPLEMENTATIONWeadoptmodulardesignfollowingtheintegrationofblockchain.Itbringsmoreflexibilitybyseparatingtheimplementationofdifferentfunctionalities,sowecouldleveragetheadvantagesoftheblockchain-basedsmartcontractwhilereducingoverhead.Figure3illustrateshowdifferentmodulesareinvolvedintheint