如何从Socket提取PortNumber?socketPort始终返回0的原因
为什么
socketPort sock始终返回0? 这问题我之前也踩过坑!原因很直白:你创建完socket之后,还没把它绑定到本地端口,也没和远程地址建立连接——此时套接字还没有关联任何有效的端口号,socketPort自然只能返回0。
具体拆解下:
socket函数只是生成了一个套接字的“空壳”,它此时既不属于任何本地端口,也没和远程服务挂上钩。socketPort的作用是返回这个套接字已经绑定的本地端口号,如果既没执行bind(绑定本地端口)也没执行connect(连接远程服务),没有可用端口可以返回,就只能给你个0了。
怎么修复?
根据你是做客户端还是服务器端,分别加上对应的操作:
如果你是客户端(连接远程服务):
创建socket后先调用connect,触发系统分配本地临时端口,之后再获取端口号:
import Network.Socket main = do let hints = defaultHints { addrSocketType = Stream } addr:_ <- getAddrInfo (Just hints) (Just "127.0.0.1") (Just "3000") sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) -- 先连接到目标地址,系统会自动分配本地临时端口 connect sock (addrAddress addr) port <- socketPort sock putStrLn $ "当前客户端使用的本地端口:" ++ show port
此时socketPort返回的是操作系统分配的临时端口(不是远程的3000端口哦)。
如果你是服务器端(监听本地端口):
先调用bind把socket绑定到指定端口,再获取端口号:
import Network.Socket main = do let hints = defaultHints { addrSocketType = Stream, addrFlags = [AI_PASSIVE] } addr:_ <- getAddrInfo (Just hints) Nothing (Just "3000") sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) -- 绑定到你指定的3000端口 bind sock (addrAddress addr) listen sock 5 port <- socketPort sock putStrLn $ "当前服务器监听的端口:" ++ show port
这时socketPort就会返回你指定的3000端口了。
内容的提问来源于stack exchange,提问作者Mahesh Uligade
相关产品推荐
相关产品推荐

