C++ Winsock 套接字错误:10038 (WSAENOTSOCK)

Posted

技术标签:

【中文标题】C++ Winsock 套接字错误:10038 (WSAENOTSOCK)【英文标题】:C++ Winsock Socket Error: 10038 (WSAENOTSOCK) 【发布时间】:2013-03-19 15:44:35 【问题描述】:

我有一个在 WinXp(i7, 2.1 Ghz) 上运行的主从应用程序 Master,而从属应用程序是一个控制器板。主站向从站发送请求,从站作为响应循环向主站发送数据。从机循环发送的数据为每 0.5 毫秒 1000 字节。 当master发出发送数据的请求时,控制台报错。

“Select() 函数错误代码:: 10038”。

这是WSAENOTSOCK的代码。

此应用程序是一个单线程应用程序,从从站接收数据。 从错误来看,套接字似乎在 select 函数检查之前已关闭。

谁能给我指个方向?

:::源代码::::

int Receive()

    int rc;
    socklen_t cli_alen;
    struct timeval to;
    fd_set read_fd, write_fd, excep_fd;

    FD_ZERO(&write_fd);
    FD_ZERO(&excep_fd);

sock_again:
    if (!_isSocketOpen) 
    
        return 0;
    
    FD_ZERO(&read_fd);
    FD_SET(_sock_fd, &read_fd);
    to.tv_sec =  0;
    to.tv_usec = 0;
    cli_alen = sizeof(SOCKADDR_IN);

    rc = select(_sock_fd+1, &read_fd, &write_fd, &excep_fd, &to);

    if (rc == 0 )  
       // Timeout
        // printf("XCP Port %d : select() timded out \n", _port);
        acess = 1;
        goto sock_again;
     
    else if (rc == SOCKET_ERROR) 
    
        // Error
        LogError("XCP: select() error %d", WSAGetLastError());
        closesocket(_sock_fd);
        return -1;
    
    else 
    
        // Data
        if (!FD_ISSET(_sock_fd, &read_fd)) 
        
            LogError("XCP: select() wrong socket descr");
            return -1;
        
        else
        
            //read data
            rc = recvfrom(_sock_fd, (char *)_recvBuf, UDP_RECVBUFLEN, 0, (LPSOCKADDR)&_saddr, &cli_alen);



:::: 已编辑 ::::

int CloseUdpConnection()

    if (closesocket(_sock_fd) == SOCKET_ERROR) 
        LogError("closesocket() error: %d", WSAGetLastError());
        return -1;
    
    _isSocketOpen = 0;
    LogError("successfully closed socket %s:%d", _address, _port);
    return 0;

::::: 调试跟踪 :::::

xcpApplication.exe -i 192.168.1.100 -p 5555
c
--> Connecting...
<-- Connection established
t
--> Setting daq signal list...
Sorting daq signal list...
Sorting done
<-- Daq signal list set
d
--> Configuring daq lists...
<-- Configuration done
r
--> Starting measurement...
<-- Measurement started

**_sock_fd: -448997078**
XCP: select() error 10038

::::: 跟踪 ::::

--> Starting measurement...
<-- Measurement started
_sock_fd: -1963260928 
_sock_fd: 0x8afb0400
XCP: select() error 10038

:::::: 跟踪 ::::

xcpApplication.exe -i 192.168.1.100 -p 5555

_sock_fd: 1936 _sock_fd: 0x790
successfully opened socket 192.168.1.100:5555

--> Connecting...
<-- Connection established
t
--> Setting daq signal list...
Sorting daq signal list...
Sorting done
<-- Daq signal list set
d
--> Configuring daq lists...
<-- Configuration done
c
--> Connecting...
<-- Connection established
r
--> Starting measurement...
<-- Measurement started
_sock_fd: 901186560 _sock_fd: 0x35b70400
XCP: select() error 10038

【问题讨论】:

由于您没有使用write_fdexcept_fd,您可以将NULL 传递给select() 另外,您将超时设置为0,这意味着您只是在检查是否有任何数据可用。您可以通过在套接字上设置非阻塞模式并调用 recvfrom 来获得相同的行为。 数据接收和传递的频率需要足够快,所以我使用立即超时,否则由于缓冲区溢出导致数据包丢失。 这不是超时的作用。 来源-MSDN Select函数:如果TIMEVAL初始化为0, 0,select会立即返回;这用于轮询所选套接字的状态。如果 select 立即返回,则 select 调用被认为是非阻塞的,并且适用非阻塞调用的标准假设。 【参考方案1】:
>net helpmsg 10038

An operation was attempted on something that is not a socket.

您可以使用shutdown() 函数安全地关闭 TCP/IP 意义上的套接字。但不要在select()poll() 使用的SOCKET 句柄上调用closesocket()

实际上,在 Win32 中,您通常更喜欢使用 WSAAsyncSelectWSAEventSelect

如果您的应用程序是单线程的并且不使用异步回调,那么您不能在 select 调用期间调用 closesocket。我看到您在致电closesocket 后立即返回。因此,您必须使用无效套接字输入函数,但 _isSocketOpen 是真的。或许您应该在调用closesocket() 时将该标志设置为false。

【讨论】:

谢谢,我不知道方便的net helpmsg [errcode] 命令! 我正在使用 UDP/IP,标志被关闭套接字功能重置。如果我将数据大小从 1000 字节减少到 972 字节,我只会在 1000 字节/0.5 毫秒时遇到此故障,它工作得非常好。一些如何在 1000 到 972 字节之间报告此错误。 附加到shutdown(),而不是closesocket(),只有当返回值为SOCKET_ERROR时才会执行。我不确定这是否可以解决之前发生的错误。我不确定这是否与内存泄漏有关。如果我错了,任何专家意见? @Pipa's:但是看——套接字描述符是0x790,但是当错误发生时_sock_fd被垃圾填满了。套接字未关闭,但您没有将真正的套接字传递给select。我猜你附近有一个缓冲区溢出,它正在覆盖你的套接字句柄。 @Pipa's:你肯定有一个错误导致_sock_fd 被破坏。尽管您可以设计您的从属服务器使其不会遇到错误,但您的服务器中仍会存在安全漏洞。

以上是关于C++ Winsock 套接字错误:10038 (WSAENOTSOCK)的主要内容,如果未能解决你的问题,请参考以下文章

Winsock - 10038 错误 - Win2K3 服务器 - 令人费解的行为

C++ winsock 错误

[mpm_winnt:error] [pid 28120:tid 15980] (OS 10038)在一个非套接字上尝试了一个操作。 : AH00332: winnt_accept: getsock

bind() 失败并出现 Windows 套接字错误 10038

MinGW 链接器错误:winsock

C++ WinSock2:连接()调用上的 WSA_INVALID_HANDLE