字符串如何分割成两段指定字符数的二进制数据,又如何转回这段字符串?【已解决】
本帖最后由 fenhanxue 于 2017-8-22 02:31 编辑问题背景:
TCPRecv ( 主套接字, 最大返回量[, 标志])
有最大返回量的限制,假设这个最大返回量为 $max
假设发送端电脑要发送一段中英文混杂文本$text 到接收端电脑,那么分两种情况
1)文本 $text 的长度 <= $max
这种情况我知道可以这样写代码:
1.1)发送端
TCPSend(主套接字,StringToBinary($text,2))
1.2)接收端
$receive = TCPRecv (主套接字,$max,1)
$receive = BinaryToString($receive,2)
这样接收端就可以最终收到完整的$text
2)文本 $text 的长度 > $max
这种情况下不知道具体应该如何对$text 进行二进制分割
假设此时:
2* $max >$text 的长度 > $max
那么也就意味着发送端需要发送两次二进制数据
第一次:TCPSend(主套接字,$data_1) ($data_1 的长度 = $max)
第二次:TCPSend(主套接字,$data_2) ($data_2 的长度 = $text 的长度 -$max)
这里的 $data_1 和 $data_2 具体应该怎么运算得到?
然后此时接收端也要收两次二进制数据才行
第一次:$receive_1 = TCPRecv (主套接字,$max,1)
第二次:$receive_2 = TCPRecv (主套接字,$max,1)
这里的$receive_1 和 :$receive_2 又应该如何转变回 $text ? 换个思路,定义二个控制字符,约定chr(1)为发送字符串开始,chr(2)为发送结束.客户端接收到chr(1),认为是字符串的开始,收到chr(2),认为发送结束,转换chr(1)与chr(2)之间的二进制数据即可 回复 2# tubaba ;假设最大返回量为9个字节
$max = 9
;假设一段文本 $text 的长度在 9 到18之间
$text
;那么这段代码是否有问题:
Local $binary = StringToBinary($text,2)
;二进制分成两部分:
$binary_1 = BinaryMid($binary,1,$max)
$binary_2 = BinaryMid($binary,1+$max)
;发送端发送两次,分别为:
TCPSend(主套接字,$binary_1);第一次
TCPSend(主套接字,$binary_2);第二次
;接收端接受两次,分别为:
$receive_1 = TCPRecv (主套接字,$max,1) ;第一次
$receive_2 = TCPRecv (主套接字,$max,1) ;第二次
;接收端完整收到的信息为:
BinaryToString($receive_1&$receive_2,2) 本帖最后由 tubaba 于 2017-8-17 15:12 编辑
存在一个数据类型转换问题,定义收到04即接收完成
Func _TCPRecv()
Local $recv, $string = ''
While 1
$recv = TCPRecv($ConnectedSocket, 9, 1)
If ($recv = '' And (Not @error)) Or @error Then ExitLoop
If $recv <> '' Then
$string &= StringRegExpReplace($recv, '(?:0x)(.+)', '$1')
If StringRight($string, 2) == '04' Then ExitLoop
EndIf
WEnd
;~ $string= BinaryToString('0x' & $string, 4)
If StringRight($string, 2) == '04' Then
$string = BinaryToString('0x' & StringTrimRight($string, 2), 4)
Else
$string = BinaryToString('0x' & $string, 4)
EndIf
If $string = '' Then Return SetError(1, 0, $string)
;~ FileWrite('out1.txt',$string)
Return SetError(0, 0, $string)
EndFunc ;==>_TCPRecv 回复 4# tubaba
假设自定义收到的 $end = '04'作为接收完成的标记,
有没有可能会遇到特殊情况:
某一段字符串 经过 stringtobinary 后,凑巧他的末尾两位 等于$end ( '04' )?
那么这样的话,就会误判以为接收完成了。
有没什么字符串,是 stringtobinary 后绝对不会出现的? 回复 5# fenhanxue
我記得範例有人有傳輸檔案的範例 中間好幾MB 都可以傳
所以理論上應該有處理這個的範例 回复 6# kk_lee69
抱歉,插楼。。。。。我看见你去官网问 大神 LarsJ。修改选定项颜色用很短的代码搞定了。。。请问,你能同时指定某列的颜色么? 回复 7# yamakawa
看來就是不行你可以去看我 另外再發問的 .......
就是我怎麼測試都不行
只是我不能理解的是 官網的 是不用另外做GDI 然後再合併進去
我們之前的方式 似乎是另外的人的是 畫了一個GDI 然後再合併進去
但是使用 官網的 那個方法 我的 複選框 功能失效 回复 8# kk_lee69
理论上,官网那个才是正宗的,因为用的是本来的数据结构,只是更改了某些参数,这个兼容性更好。但是我没找到资料$CDDS_ITEMPREPAINT之类的参数到底有什么关系,为什么有时候有些参数可以,有些不行,,,
gdi那个是直接干掉原来现实的部分直接画上去。所以原来有的某些特性,比如复选框,就没有了。需要我们自己画 本帖最后由 fenhanxue 于 2017-8-17 18:20 编辑
回复 6# kk_lee69
可能是这个帖子:
http://autoitx.com/forum.php?mod=viewthread&tid=17177&highlight=tcp%2B%CE%C4%BC%FE
范例是档案传输 ,几个关键代码为
发送端: FileOpen($hfile,16)
While
$data = FileRead($id,$max);不断循环读取指定长度的二进制数据
If @error=-1 Then ExitLoop
TCPSend($netid,$data)
WEnd接收端: $file = FileOpen ($hfile,16+1)
While
$receive = TCPRecv($ConnectedSocket,$max)
If @error=-1 Then ExitLoop
FileWrite($file,Binary($data))
WEnd我想传输的是程序里的一段长文本(假设为$text),而不是文件,所以需要对 $text 进行分割,而如何将这个 $text 变成二进制数据,并且按照指定的字符长度进行分割,原理不是很懂。
当然如果笨一点的办法,可以参考上面的范例这样写:
接收端:
先把 $text 写到一个txt档案里,然后套用上面的范例代码,读取这个档案,来发送。
接收的时候,也套用上面的代码,接收到一个txt档案里,然后再FileOpen ($hfile,0) 来读取这个txt档案 回复 8# kk_lee69
我这边的测试效果好搞笑
{:face (394):} 好像没有更新?!要点一下其他行才会变化 本帖最后由 yamakawa 于 2017-8-17 19:35 编辑
回复 8# kk_lee69
好像可以了。。。。。
修改$NM_CLICK消息为 Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
Local $Index = DllStructGetData($tInfo, "Index"), _
$X = DllStructGetData($tInfo, "X")
If $X < 18 Then ;使用x坐标来判断是否在复选框上点击
If $aShowdata2[$Index] = 4096 Then
$aShowdata2[$Index] = 8192 ;4096未选中 8192选中
Else
$aShowdata2[$Index] = 4096 ;4096未选中 8192选中
EndIf
EndIf
Local $Info = DllStructCreate($tagNMLVDISPINFO, $ilParam)
DllStructSetData($Info, "State", $aShowdata2[$Index]) ;设置复选框状态
_GUICtrlListView_RedrawItems($hWndFrom, $Index, $Index);<====好像可以了。。。。复选框正常
现在我的问题是。。不知道怎么可以单独设置某个列的颜色。。。原来那个代码好像不起作用了。。好奇怪 回复 10# fenhanxue
抱歉,楼主,在你的帖子插楼。。。
我想传输的是程序里的一段长文本(假设为$text),而不是文件,所以需要对 $text 进行分割,而如何将这个 $text 变成二进制数据,并且按照指定的字符长度进行分割,原理不是很懂
这个的话,可以先用StringToBinary转换成二进制数据,然后BinaryLen可以获取字节数,然后根据字节数进行判断,分解成小于max的数据,用BinaryMid(提取二进制变量的若干字节.) 回复 13# yamakawa
另外。。tcpsend成功的话,会返回成功发送的字节数,可以把这个当参数传递给下一次传输。例如这次传输了2048个字节,那么下次binarymid就从2049开始 本帖最后由 yamakawa 于 2017-8-17 20:22 编辑
回复 5# fenhanxue
另外。4楼说的定义04就是接受完成的意思。一般来说。传输数据不会是04结尾的,但是如果实在怕不保险的话,
你可以定义某个开始特征码和完成特征码。。
第一次发送开始码,接收端收到后就知道下次开始是发送的多次信息,
然后全部发送完成后,发送端再发送完成码,接收端知道信息已经接收完毕了。那么就对之前接收到的数据进行合并,转换操作
页:
[1]
2