套接字窗口例外。读取访问冲突

Posted

技术标签:

【中文标题】套接字窗口例外。读取访问冲突【英文标题】:Exception with socket windows. Read access violation 【发布时间】:2015-07-02 12:19:24 【问题描述】:

只是想用winsock打开一个套接字。我从 Visual Studio 收到一条错误消息,指出我在 ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 上存在读取访问冲突

我的整个代码都在那里:

ListenSocket = INVALID_SOCKET;
ClientSocket = INVALID_SOCKET;
 WORD wVersionRequested;
    WSADATA wsaData;
    int wsaerr;
    wVersionRequested = MAKEWORD(2, 2);
    wsaerr = WSAStartup(wVersionRequested, &wsaData);
    if (wsaerr != 0)
    
        printf("Server: The Winsock dll not found!\n");
        WSACleanup();
        return 0;
    

    else
    
        printf("Server: The Winsock2 dll found \n");
    
    /* SOCKET is simply a UINT, created because
 on Unix sockets are file descriptors(UINT) but not in windows
 so new type SOCKET was created */
    cout << AF_INET << endl ;
    cout << SOCK_STREAM << endl ;
    cout << IPPROTO_TCP << endl ;
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(ListenSocket == INVALID_SOCKET)
    
        cerr << "Server: Error initializing socket!n" << endl;
        WSACleanup();
        return 0;
    

    /* The SOCKADDR_IN structure is used by
 Win Sockets to specify an endpoint address
 to which the socket connects */
    sockaddr_in service,client ;
    service.sin_family = AF_INET;
    service.sin_port = htons(port);
    service.sin_addr.s_addr = INADDR_ANY;

    /* bind just links the socket
 with the sockaddr_in struct we initialized */
    if(bind(ListenSocket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
    
        printf("Server: Error binding socket to port \n");
        WSACleanup();
        return 0;
    

    /* wait for incoming connections */
    if(listen(ListenSocket,10)==SOCKET_ERROR)
        printf("listen(): Error listening on socket %d\n", WSAGetLastError());
    else
    
        printf("Server: Waiting for connections...\n");
    

    /* accept connections */

    printf("Server: Waiting for a client to connect...\n");
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET) 
        wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
     else 
        wprintf(L"Client connected.\n");
        acceptConns();

    

很想得到一些帮助,因为我不知道为什么它不起作用。

提前致谢

编辑:我正在使用以下代码在线程中创建该服务器。看来这就是我首先收到错误的原因

DWORD WINAPI myThread(LPVOID lpParameter)

    tcp_server* server = (tcp_server*)lpParameter ;
    server->start_listening(); // The above function
    return 0 ;

.....

HANDLE myHandle = CreateThread(0, 0, myThread, server, 0,NULL);

【问题讨论】:

你有没有按照微软官方教程的建议改用getaddrinfo返回的参数? msdn.microsoft.com/en-us/library/windows/desktop/… 我有但是getaddrinfo函数没有定义 你包括哪个 WinSock 标头? 啊,原来 getaddrinfo 是在 中声明的。你也加入了那个吗? 能否请您发布tcp_server 类的或多或少完整的定义? 【参考方案1】:

我在ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 上存在读取访问冲突

该行没有明显的读取访问。

但是,由于您显示的代码(出于诊断目的不完整)位于类方法 tcp_server::start_listening() 中,而 ListenSocket 可能是该类的成员,您正在通过 @ 调用 start_listening() 987654325@对象指针就是传递给线程的,按理说

    唯一可能发生的读取是在分配给ListenSocket 成员时对隐式this 指针的访问。

    当线程调用start_listening() 时,被指向的tcp_server 对象很可能在内存中无效(或者,至少在调用socket() 时,因为您确实初始化了ListenSocket预先)。如果这是真的,分配给ListenSocket 将是未定义的行为,这CAN会导致访问冲突错误(以及其他类型的错误,如果有的话)。 p>

但是,您没有说明在调用CreateThread() 之前如何创建server 对象,或者在CreateThread() 退出后如何处理该对象,所以这个推理只是一个(有根据的)猜测,除非您显示更完整的代码示例。

【讨论】:

好的,感谢您的回答,我可以在编辑中向您展示更完整的代码。尽快做(我现在在手机上) 你完全正确,只是弄明白了:我正在实例化一个新的 tcp_server 对象,而不是使用我在调用线程时使用的类成员。非常感谢你帮助我:)。在没有完整代码的情况下找出问题并提出可能的问题,这绝对值得一票。

以上是关于套接字窗口例外。读取访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

允许该应用创建网络套接字是啥意思

ORACLE数据连接报错无法从套接字读取更多的数据怎么解决

如何立即终止套接字 IO 操作上的线程阻塞?

原始套接字和普通的TCP套接字有啥不同?

CORBA 代理/代理通过 HTTP 还是通过套接字访问(对于 PHP)?

Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试