如何发送字节数组
net-send仅仅接受string作为参数,也就是说只能发送字符串。
后来才发现,原来这只是这个API的接口,通过字符串仍然能够发送二进制数据,比如:
> (net-send socket "\019\000") 2只需要前面加上\转义符号即可。
如何发送16位整数,并按照big-endian顺序发送
答案是pack。看下面的例子:
> (set 'socket (net-connect "localhost" 8889)) 5 > (set 'size (pack ">u" 19)) "\000\019" > (net-send socket size) 2
注意,这里的低地址是从左开始的,也就是整数19的高字节0位于最低地址上,因此的确是big-endian.
如何在接收到的二进制数据中获取指定位置的字节
答案是address和+,下面有两个辅助函数:
(define (pick-byte buffer offset) (get-char (+ (address buffer) offset))) (define (pick-char buffer offset) (char (pick-byte buffer offset)))
(unless (net-receive socket message 13) (quit-for-error)) (println (pick-byte message 0)) (println (pick-char message 1))先从TCP连接中读取13个字节,存放在message symbol中。然后用address获取message在内存中的其实地址,再用+获取第n个字节的内存地址,这时得到的字节,可以用char将其转换成ASCII字符。
如何在接收到的二进制数据中获取连续的字节
下面有两个函数,一个获取连续字节,一个获取连续字符串,前者返回list, 后者返回字符串
;; extract the bytes from buffer in [start, end) and return it as a list (define (pick-bytes buffer start end) (let (l '()) (dotimes (x (- end start)) (push (pick-byte buffer (+ start x)) l -1)))) ;; extract the string from buffer in [start, end) and return it as a string (define (pick-string buffer start end) (let (l "") (dotimes (x (- end start)) (push (pick-char buffer (+ start x)) l -1)) ))
(unless (net-receive socket message 13) (quit-for-error)) (println (int (append "0x" (pick-string message 1 5))))解析出来的是"000D", 加上0x后变成"0x000D" 用int函数转换后变成13.