Haskell实现Socket客户端连接报WSAEADDRNOTAVAIL错误排查
报错原因
报错和地址配置直接相关,同时代码混淆了TCP客户端和服务端的逻辑:
SockAddrInet的第二个参数为网络字节序的目标IP地址,传入0对应INADDR_ANY(即0.0.0.0),该地址仅用于服务端绑定监听所有本地网卡,不能作为客户端connect的目标地址,这是触发WSAEADDRNOTAVAIL错误的直接原因。- 你需要以客户端身份连接已有服务,不需要调用
listen、accept方法,这两个是服务端监听、接收连接的专属接口,客户端在connect成功后即可直接使用socket句柄收发数据。
修复方案
- 替换connect的目标地址:连接本机服务时使用127.0.0.1对应的IP值,不要用0作为目标IP。端口参数注意使用网络字节序,推荐直接用
getAddrInfo做地址解析,避免手动处理字节序出错。 - 删除connect之后的
listen、accept相关逻辑。
正确实现示例
import Network.Socket main :: IO () main = do putStrLn "Create socket" sock_logger <- socket AF_INET Stream defaultProtocol putStrLn "Connect to logger service" -- 解析目标地址:本机127.0.0.1的5000端口 addrInfos <- getAddrInfo (Just defaultHints { addrSocketType = Stream }) (Just "127.0.0.1") (Just "5000") let targetAddr = addrAddress (head addrInfos) connect sock_logger targetAddr putStrLn "Connected to logger service on port 5000" -- 后续可直接通过sock_logger调用send、recv收发数据 -- 通信结束后关闭socket close sock_logger
如果需要手动构造SockAddrInet,127.0.0.1对应地址可通过tupleToHostAddress (127,0,0,1)获取,写法为SockAddrInet 5000 (tupleToHostAddress (127,0,0,1)),注意该写法仅支持IPv4地址。
内容的提问来源于stack exchange,提问作者kepich
相关产品推荐
相关产品推荐

