【问题标题】:Why would WSASendMsg return WSAEINVAL for a socket returned from accept()?为什么 WSASendMsg 会为从 accept() 返回的套接字返回 WSAEINVAL?
【发布时间】:2013-12-05 15:51:33
【问题描述】:

我有一个 Windows 服务器应用程序

  • 显然是 WSAStartup()
  • 在 TCP 端口 X 上侦听()
  • accept() 传入连接
  • ioctlsocket() 套接字进入非阻塞模式
  • 尝试使用 WSASendMsg 回复

我收到 WSAEINVAL 错误代码,这可能意味着: 'socket没有被bind绑定,或者socket不是用overlapped flag创建的。'

在这种情况下,调用 bind() 是没有意义的,因为套接字已经与本地和远程地址连接。并且套接字也绝对不是使用重叠标志创建的。

那么,我得到从那行文档中逃脱的错误的真正原因是什么?

【问题讨论】:

    标签: windows sockets winsock2


    【解决方案1】:

    AFAICWO:因为我使用accept() 来监听 TCP 套接字连接请求,所以接受返回给我的是一个面向连接的套接字。所以我必须使用WSASend() 而不是WSASendMsg()。 MSDN 文档确实有这个花絮,最终让我知道我出错的地方:

    WSASendMsg 函数只能与数据报和原始数据一起使用 插座。

    换句话说,WSASendMsg() 仅适用于 无连接 场景,例如 UDP、ICMP 或您自己编写数据包的任何其他原始套接字。

    (也许我也可以改用WSASendTo():)

    在面向连接的套接字上,lpTo 和 iToLen 参数被忽略; 在这种情况下,WSASendTo 等价于 WSASend。

    【讨论】:

    • MSDN 的措辞似乎草率。它应该说“数据报 sockets 或原始套接字”。
    • 非常感谢,它让我免于扯掉头发。不过要澄清一点:文档在最顶部说 WSASendMsg 函数从已连接和未连接的套接字发送数据和可选控制信息。”?这里的“已连接”是指原始套接字吗?因为我完全认为它意味着“连接”意味着你可以在面向连接的套接字上使用它......
    • @user541686 欢迎您!通过连接,我只是意味着我已经接受了一个 TCP 连接请求,即它是一个流套接字连接。让我更新我的答案以澄清......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多