C++ Winsock 应用程序访问冲突

C++ Winsock App Access Violation

我正在为 C++ Winsock 服务器和客户端使用来自 MSDN 的源代码,在服务器端我将大部分代码放在函数中并且出现访问冲突错误。我的完整来源如下。

任何帮助都将非常有用,在此先感谢! 这是我的 j420s,cpp 文件。

#include "j420s.h"
//Source From : MSDN Winsock Server Code.
//Original Source : https ://msdn.microsoft.com/en-   us/library/windows/desktop/ms737593(v=vs.85).aspx
int __cdecl main(void) {

WSADATA wsaData;
int iResult = NULL;

SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;

struct addrinfo *MySocketResult = NULL;
struct addrinfo MySocket;

int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;

// Initialize Winsock
iResult = SocketInit(iResult, &wsaData);
if (iResult == 1){

    return 1;

}

ZeroMemory(&MySocket, sizeof(MySocket));
MySocket.ai_family = AF_INET;
MySocket.ai_socktype = SOCK_STREAM;
MySocket.ai_protocol = IPPROTO_TCP;
MySocket.ai_flags = AI_PASSIVE;

// Resolve the server address and port
iResult = SocketAddrInfo(iResult, &MySocket, MySocketResult);


// Create a SOCKET for connecting to server
ListenSocket = SocketCreate(ListenSocket, MySocketResult);
if (ListenSocket == 1){

    return 1;

}

// Setup the TCP listening socket
iResult = SocketBind(iResult, ListenSocket, MySocketResult);
if (iResult == 1) {

    return 1;

}

iResult = SocketListen(iResult, ListenSocket, MySocketResult);
if (iResult == 1) {

    return 1;

}

// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
    printf("accept failed with error: %d\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}

// No longer need server socket
closesocket(ListenSocket);

// Receive FOREVER!
while (1 == 1){
  do {

    iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);

      if (iResult > 0) {

        printf("Bytes received: %d\n", iResult);

        // Echo the buffer back to the sender
        iSendResult = send(ClientSocket, recvbuf, iResult, 0);

        if (iSendResult == SOCKET_ERROR) {

            printf("send failed with error: %d\n", WSAGetLastError());

            closesocket(ClientSocket);
            WSACleanup();

            return 1;

        }

        printf("Bytes sent: %d\n", iSendResult);

    }

  } while (iResult > 0);

}

// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);

if (iResult == SOCKET_ERROR) {

    printf("shutdown failed with error: %d\n", WSAGetLastError());

    closesocket(ClientSocket);
    WSACleanup();

    return 1;

}

// cleanup
closesocket(ClientSocket);
WSACleanup();
system("pause");
return 0;

}

int SocketAddrInfo(int iResult, addrinfo* MySocket, addrinfo*  MySocketResult){

iResult = getaddrinfo(NULL, DEFAULT_PORT, MySocket, &MySocketResult);

if (iResult != 0) {

    printf("getaddrinfo failed with error: %d\n", iResult);

    WSACleanup();

    return 1;

}

return iResult;

}
// Socket initialization
int SocketInit(int iResult, WSADATA *wsaData){

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

if (iResult != 0) {

    printf("WSAStartup failed with error: %d\n", iResult);

    std::cout << "Server closing in 5 ";

    for (int i = 4; i > 0; i--){

        Sleep(1 * 1000);

        cout << i << " ";

    }

    cout << "Server closing now!" << endl;

    return 1;

}

return iResult;

}
// Socket create function to create a socket for connecting to our server.
SOCKET SocketCreate(SOCKET ListenSocket, addrinfo* MySocketResult){

ListenSocket = socket( MySocketResult->ai_family, MySocketResult-  >ai_socktype, MySocketResult->ai_protocol );

if ( ListenSocket == INVALID_SOCKET ) {

    printf("Socket failed with error: %ld\n", WSAGetLastError());

    freeaddrinfo(MySocketResult);
    WSACleanup();

    std::cout << "Server closing in 5 ";

    for (int i = 4; i > 0; i--){

        Sleep(1 * 1000);

        cout << i << " ";

    }

    cout << "Server closing now!" << endl;

    return 1;

}

return ListenSocket;

}

// Socket bind function for binding our socket to an address for incoming         connections.
int SocketBind(int iResult, SOCKET ListenSocket, addrinfo* MySocketResult) {

iResult = bind(ListenSocket, MySocketResult->ai_addr, (int)MySocketResult->ai_addrlen);

if (iResult == SOCKET_ERROR) {

    printf("Bind failed with error: %d\n", WSAGetLastError());

    freeaddrinfo(MySocketResult);
    closesocket(ListenSocket);
    WSACleanup();

    std::cout << "Server closing in 5 ";

    for (int i = 4; i > 0; i--){

        Sleep(1 * 1000);

        cout << i << " ";

    }

    cout << "Server closing now!" << endl;

    return 1;

}

return iResult;

}

// Socket listen function to listen for incoming connections.
int SocketListen(int iResult, SOCKET ListenSocket, addrinfo* MySocketResult)  {

freeaddrinfo(MySocketResult);

iResult = listen(ListenSocket, SOMAXCONN);

if (iResult == SOCKET_ERROR) {

    printf("Listen failed with error: %d\n", WSAGetLastError());

    closesocket(ListenSocket);
    WSACleanup();

    std::cout << "Server closing in 5 ";

    for (int i = 4; i > 0; i--){

        Sleep(1 * 1000);

        cout << i << " ";

    }

    cout << "Server closing now!" << endl;

    return 1;

}

return iResult;

}

// Socket accept connection function.

SOCKET SocketAcceptConnection(SOCKET ClientSocket, SOCKET ListenSocket) {

ClientSocket = accept(ListenSocket, NULL, NULL);

if (ClientSocket == INVALID_SOCKET) {

    printf("accept failed with error: %d\n", WSAGetLastError());

    closesocket(ListenSocket);
    WSACleanup();

    std::cout << "Server closing in 5 ";

    for (int i = 4; i > 0; i--){

        Sleep(1 * 1000);

        cout << i << " ";

    }

    cout << "Server closing now!" << endl;

    return 1;

}

closesocket(ListenSocket);

return 0;

}

Here is my j420s.h file.
#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using std::cout;
using std::endl;

// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "10187"
int SocketInit(int, WSADATA*);
int SocketAddrInfo(int, addrinfo*, addrinfo*);
SOCKET SocketCreate(SOCKET, addrinfo* );
int SocketBind(int, SOCKET, addrinfo* );
int SocketListen(int, SOCKET, addrinfo* );
SOCKET SocketAcceptConnection(SOCKET, SOCKET );

此函数中存在访问冲突:

int SocketAddrInfo(int iResult, addrinfo* MySocket, addrinfo* MySocketResult){

iResult = getaddrinfo(NULL, DEFAULT_PORT, MySocket, &MySocketResult);

if (iResult != 0) {

    printf("getaddrinfo failed with error: %d\n", iResult);

    WSACleanup();

    return 1;

}

return iResult;

}

我这样调用函数:

iResult = SocketAddrInfo(iResult, &MySocket, MySocketResult);

我认为这与我的指示有关...

再说一次,任何帮助都将非常有用!再次感谢!

getaddrinfo() 的结果将在函数 SocketAddrInfo() 返回时被丢弃,函数 main() 中的 MySocketResult 仍然是 NULL

之后,此 NULL 被传递给 SocketCreate(),并通过 MySocketResult 取消引用。它应该会导致粉碎。

您应该将指向 MySocketResult 的指针传递给 SocketAddrInfo() 并让 getaddrinfo() 修改它。

int SocketAddrInfo(int iResult, addrinfo* MySocket, addrinfo** MySocketResult){
    iResult = getaddrinfo(NULL, DEFAULT_PORT, MySocket, MySocketResult);
    if (iResult != 0) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }
    return iResult;
}

如何调用:

iResult = SocketAddrInfo(iResult, &MySocket, &MySocketResult);