在标准机器学习中使用 TCP
Using TCP in Standard ML
我正在尝试用标准 ML 编写一个最小的 TCP 服务器,但出现了一些我不理解的类型错误。到目前为止我得到的是
fun sendHello sock =
let val res = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"
val wds = map (fn c => Word8.fromInt (Char.ord c)) (String.explode res)
val slc = ArraySlice.full (Array.fromList wds)
in
Socket.sendArr (sock, slc)
Socket.close sock
end
fun acceptLoop serv =
let val (s, _) = Socket.accept serv
in print "Accepted a connection...\n";
sendHello s;
acceptLoop serv
end
fun serve () =
let val s = INetSock.TCP.socket()
in Socket.Ctl.setREUSEADDR (s, true);
Socket.bind(s, INetSock.any 8989);
Socket.listen(s, 5);
print "Entering accept loop...\n";
acceptLoop s
end
后两个函数工作正常(如果我注释掉 sendHello
行,它们会毫无怨言地进行类型检查,并设置一个每次客户端连接时打印 Accepted a connection...
的服务器)。
根据我从 Socket struct
中了解到的情况,sendArr
应该采用一个套接字元组和一个 Word8ArraySlice.slice
,我有理由相信我正在提供。
SMLNJ
- ArraySlice.full (Array.fromList (map (fn c => Word8.fromInt (Char.ord c)) (String.explode "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"))) ;;
val it =
SL
{base=[|0wx48,0wx54,0wx54,0wx50,0wx2F,0wx31,0wx2E,0wx31,0wx20,0wx32,0wx30,
0wx30,...|],start=0,stop=49} : Word8.word ArraySlice.slice
-
我得到的错误是
- fun sendHello sock =
let val res = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"
val wds = map (fn c => Word8.fromInt (Char.ord c)) (String.explode res)
val slc = ArraySlice.full (Array.fromList wds)
in
Socket.sendArr (sock, slc)
Socket.close sock
end ;;
= = = = = = = stdIn:35.8-36.25 Error: operator and operand don't agree [tycon mismatch]
operator domain: ('Z,Socket.active Socket.stream) Socket.sock *
?.Word8ArraySlice.slice
operand: ('Z,Socket.active Socket.stream) Socket.sock *
Word8.word ArraySlice.slice
in expression:
Socket.sendArr (sock,slc)
-
任何人都可以告诉我我需要做什么才能使它正常工作吗?
事实证明 Word8
的 ArraySlice
与 Word8ArraySlice
不是一回事。为了从字符串中获取后者,您需要使用适当的数组调用 packString
。我决定改用 Vector
s,这意味着我可以做 Word8VectorSlice.full (Byte.stringToBytes res)
来获得我可以通过 Socket.sendVec
发送的东西。以下工作正常:
fun sendHello sock =
let val res = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"
val slc = Word8VectorSlice.full (Byte.stringToBytes res)
in
Socket.sendVec (sock, slc);
Socket.close sock
end
我正在尝试用标准 ML 编写一个最小的 TCP 服务器,但出现了一些我不理解的类型错误。到目前为止我得到的是
fun sendHello sock =
let val res = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"
val wds = map (fn c => Word8.fromInt (Char.ord c)) (String.explode res)
val slc = ArraySlice.full (Array.fromList wds)
in
Socket.sendArr (sock, slc)
Socket.close sock
end
fun acceptLoop serv =
let val (s, _) = Socket.accept serv
in print "Accepted a connection...\n";
sendHello s;
acceptLoop serv
end
fun serve () =
let val s = INetSock.TCP.socket()
in Socket.Ctl.setREUSEADDR (s, true);
Socket.bind(s, INetSock.any 8989);
Socket.listen(s, 5);
print "Entering accept loop...\n";
acceptLoop s
end
后两个函数工作正常(如果我注释掉 sendHello
行,它们会毫无怨言地进行类型检查,并设置一个每次客户端连接时打印 Accepted a connection...
的服务器)。
根据我从 Socket struct
中了解到的情况,sendArr
应该采用一个套接字元组和一个 Word8ArraySlice.slice
,我有理由相信我正在提供。
SMLNJ
- ArraySlice.full (Array.fromList (map (fn c => Word8.fromInt (Char.ord c)) (String.explode "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"))) ;;
val it =
SL
{base=[|0wx48,0wx54,0wx54,0wx50,0wx2F,0wx31,0wx2E,0wx31,0wx20,0wx32,0wx30,
0wx30,...|],start=0,stop=49} : Word8.word ArraySlice.slice
-
我得到的错误是
- fun sendHello sock =
let val res = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"
val wds = map (fn c => Word8.fromInt (Char.ord c)) (String.explode res)
val slc = ArraySlice.full (Array.fromList wds)
in
Socket.sendArr (sock, slc)
Socket.close sock
end ;;
= = = = = = = stdIn:35.8-36.25 Error: operator and operand don't agree [tycon mismatch]
operator domain: ('Z,Socket.active Socket.stream) Socket.sock *
?.Word8ArraySlice.slice
operand: ('Z,Socket.active Socket.stream) Socket.sock *
Word8.word ArraySlice.slice
in expression:
Socket.sendArr (sock,slc)
-
任何人都可以告诉我我需要做什么才能使它正常工作吗?
事实证明 Word8
的 ArraySlice
与 Word8ArraySlice
不是一回事。为了从字符串中获取后者,您需要使用适当的数组调用 packString
。我决定改用 Vector
s,这意味着我可以做 Word8VectorSlice.full (Byte.stringToBytes res)
来获得我可以通过 Socket.sendVec
发送的东西。以下工作正常:
fun sendHello sock =
let val res = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello world!\r\n\r\n"
val slc = Word8VectorSlice.full (Byte.stringToBytes res)
in
Socket.sendVec (sock, slc);
Socket.close sock
end