Haskell数据报UDP套接字:接收有效,但发送无效

问题描述 投票:1回答:1

为了了解Haskell中的网络通信如何工作,我正在实现类似回波的简单UDP服务器。它应该在本地主机(端口7331)上通过IPv6侦听,接收消息并将它们回显给与另一个字符串连接的发件人。

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import Control.Concurrent
import Control.Exception
import Control.Monad (forever)
import System.IO (
        IOMode (ReadWriteMode)
        , hPutStrLn
                 )
import qualified Data.ByteString as BS

main = do
    sock <- socket AF_INET6 Datagram defaultProtocol
    let hints = defaultHints { addrFamily = AF_INET6, addrSocketType = Datagram}
    serverAddr <- addrAddress . head <$> getAddrInfo (Just hints) (Just "::1") (Just "7331")
    print serverAddr
    bind sock serverAddr
    print sock
    forever $ do
        receivedStuff <- recvFrom sock 65535    -- blocks
        forkIO $ bracket newSendSocket close (serveReceive receivedStuff)

serveReceive :: (BS.ByteString, SockAddr) -> Socket -> IO ()
serveReceive (msg, fromAddr) sendSocket = do
    putStrLn $ "Got message " ++ show msg ++ " from " ++ show fromAddr
    sendTo sendSocket ("Hi, thx for " `BS.append` msg) fromAddr
    putStrLn "sent response"
    return ()

newSendSocket :: IO Socket
newSendSocket = socket AF_INET6 Datagram defaultProtocol

我正在使用netcat测试服务器的功能:nc -u -6 "localhost" 7331

服务器接收到消息,并能够将其放入标准输出。但是响应永远不会显示在netcat中。

知道我在做什么错吗?据我所知,在使用bind发送数据之前,不需要绑定(connect)或sendTo数据报套接字。

sockets haskell udp
1个回答
0
投票

您为什么要打开新的套接字进行发送?没必要如果您只是重新使用现有的套接字,那么一切正常。或者,我们可以使用wireshark进行查看。

使用新套接字进行响应(有问题的代码发布)

sendTo返回值建议发送正确的字节数。查看鲨鱼时,我们会在电线上看到响应,但是该响应随后被ICMP目标端口不可访问拒绝(nc不接受来自其他端口的消息)。

使用原始插座*

如果我们不专门为响应创建套接字,而只是重新使用原始套接字,那么事情将按您期望的那样运行-就好了。

© www.soinside.com 2019 - 2024. All rights reserved.