【问题标题】:getaddrinfo (WinAPI pure C) Visual C++ 2010 Access violation Errorgetaddrinfo(WinAPI 纯 C)Visual C++ 2010 访问冲突错误
【发布时间】:2012-09-05 13:40:13
【问题描述】:
BOOL sendHTTPdata(char* data){
    //MessageBox(NULL,data, "aaa!",MB_ICONEXCLAMATION | MB_OK);

    char  *s=malloc(sizeof(char)*5000);
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result= NULL,
                    *ptr = NULL,
                    hints={0};
    char recvbuf[DEFAULT_BUFLEN];
    int iResult;
    int recvbuflen = DEFAULT_BUFLEN;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        //printf("WSAStartup failed with error: %d\n", iResult);
        MessageBox(NULL,"WSAStartup failed with error: %d\n", "Error!",MB_ICONEXCLAMATION | MB_OK);
        return FALSE;
    }

    memset (&hints, 0, (sizeof (hints)+1000));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    // Resolve the server address and port
    //MessageBox(NULL,"test2", "Error!",MB_ICONEXCLAMATION | MB_OK);

    iResult = getaddrinfo("example.com","80", &hints, &result);
    //return FALSE;
    if ( iResult != 0) {
        sprintf(s, "getaddrinfo failed with error: %d\n",iResult);
        MessageBox(NULL,s, "Error!",MB_ICONEXCLAMATION | MB_OK);
        WSACleanup();
        return FALSE;
    }
    MessageBox(NULL,"test", "Error!",MB_ICONEXCLAMATION | MB_OK);
    // Attempt to connect to an address until one succeeds
    //return FALSE;
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
           sprintf(s, "socket failed with error: %ld\n",WSAGetLastError());
        MessageBox(NULL,s, "Error!",MB_ICONEXCLAMATION | MB_OK);
        WSACleanup();
        return FALSE;
        }

        // Connect to server.
        iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
       MessageBox(NULL,"Unable to connect to server!\n", "Error!",MB_ICONEXCLAMATION | MB_OK);
        WSACleanup();
        return FALSE;

    }

    // Send an initial buffer
    iResult = send( ConnectSocket, data, (int)strlen(data), 0 );
    if (iResult == SOCKET_ERROR) {
        sprintf(s,"send failed with error: %d\n",WSAGetLastError());
        MessageBox(NULL,s, "Error!",MB_ICONEXCLAMATION | MB_OK);
        closesocket(ConnectSocket);
        WSACleanup();
        return FALSE;
    }

    //printf("Bytes Sent: %ld\n", iResult);
    sprintf(s,"Bytes Sent: %ld\n",iResult);
    MessageBox(NULL,s, "Error!",MB_ICONEXCLAMATION | MB_OK);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        //printf("shutdown failed with error: %d\n", WSAGetLastError());
        sprintf(s,"shutdown failed with error: %d\n", WSAGetLastError());
        MessageBox(NULL,s, "Error!",MB_ICONEXCLAMATION | MB_OK);

        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
        {
            MessageBox(NULL,recvbuf, "success!",MB_ICONEXCLAMATION | MB_OK);
        }
        else if ( iResult == 0 )
            MessageBox(NULL,"Connection closed\n", "Error!",MB_ICONEXCLAMATION | MB_OK);
        else {
            sprintf(s,"recv failed with error: %d\n", WSAGetLastError());
            MessageBox(NULL,s, "Error!",MB_ICONEXCLAMATION | MB_OK);
        }
    } while( iResult > 0 );

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return TRUE;
}

当我用 Visual C++ 2010 编译它时,会出现访问冲突错误,但如果我用 Visual C++ 6.0 编译它,它就可以工作......

这是我在错误日志中看到的:

First-chance exception at 0x1027d22f (msvcr100d.dll) in Work Time Managment.exe: 0xC0000005: Access violation writing location 0x00130000.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
First-chance exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
Unhandled exception at 0xfefefefe in Work Time Managment.exe: 0xC0000005: Access violation reading location 0xfefefefe.
The program '[1456] Work Time Managment.exe: Native' has exited with code 0 (0x0).

怎么了……?为什么不能在 Visual C++ 2010 中使用 getaddrinfo ???? 我在代码中使用的这个库:

#define WIN32_LEAN_AND_MEAN
#define _WSPIAPI_COUNTOF
#include "windows.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "stdio.h"
#pragma comment (lib, "Ws2_32.lib")

【问题讨论】:

  • 总是当你遇到这样的崩溃时,你的第一反应应该是在调试器中运行你的程序。如果将帮助您找到崩溃的位置,还可以让您检查可能导致崩溃的变量。
  • DEFAULT_BUFLEN 的值是多少?对于堆栈来说,它可能太大了。

标签: c visual-studio-2010 winapi visual-c++ winsock2


【解决方案1】:

这是个问题:

memset (&hints, 0, (sizeof (hints)+1000)); 

因为它将写入 1000 字节的内存,它不应该,导致未定义的行为。不需要调用memset(),因为hints 已经初始化。但是,正确的用法是:

memset (&hints, 0, sizeof(hints));

我认为问题出在代码的其他地方,因为我使用 VC2010 成功执行了 getaddrinfo()。这是我使用的来源:

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <string.h>

int main()
{
    WSADATA wsaData;
    struct addrinfo *result= NULL, hints={0}; 
    int iResult;

    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);

    if (iResult != 0)
    {
        fprintf(stderr, "Startup failure: %d\n", iResult);
    }
    else
    {
        /* Identical behaviour with and without the memset(). 
        memset(&hints, 0, sizeof(hints)); */

        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;

        iResult = getaddrinfo("localhost", "80", &hints, &result);
        if (0 != iResult)
        {
            fprintf(stderr, "failure: %d\n", iResult);
        }
        else
        {
            printf("Success\n");
        }

        WSACleanup();
    }
    return 0;
}

【讨论】:

  • 我已经用 ZeroMemory( &hints, sizeof(hints) );但在 Visual C++ 2010 中出现同样的错误
  • @Febi,DEFAULT_BUFLEN的值是多少?
  • 我认为 Visual C++ 2010 编译器或配置可能存在问题?否则我不明白为什么不能在 VC++ 2010 中工作而在 VC++ 6.0 中工作
  • 这个我也试过 memset (&hints, 0, sizeof(hints));但不起作用...在 VC++ 2010 中
  • @Febi,用成功执行的小程序更新了答案。
【解决方案2】:

最后我解决了我的问题,getaddrinfo 没有用,因为我已经定义了 _WSPIAPI_COUNTOF #define _WSPIAPI_COUNTOF 通过删除这一行一切正常......

感谢大家的回复......并试图帮助我。 hmjd 代码是正确的,如果有人要在 winsock2 上编写,请使用 hmjd 以前编写的代码,但如果您不想出错,请记住不要定义 _WSPIAPI_COUNTOF :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    相关资源
    最近更新 更多