Search code examples
c++winsockaccess-violation

C++ Winsock App Access Violation


I am using the source code from the MSDN for the C++ Winsock Server & Client, on the server side I am putting most of the code in functions and am having a access violation error. My complete source is below.

Any help would be great, thanks in advance! This is my j420s,cpp file.

#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 );

The access violation is somewhere in this function:

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;

}

I call the function like so:

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

I believe it's something to do with my pointers...

Again, any help would be great! Thanks again!


Solution

  • The result from getaddrinfo() will be thrown away on returning from the function SocketAddrInfo(), and MySocketResult in function main() remains NULL.

    After that, this NULL is passed to SocketCreate(), and it is dereferenced via MySocketResult. It should cause crush.

    You should pass a pointer to MySocketResult to SocketAddrInfo() and have getaddrinfo() modify it.

    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;
    }
    

    How to call:

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