0


I am new to C++ and I am currently learning from a tutorial how to use winsock(2).
However I run into a problem with my server. I have no idea how it happens.

#include "stdafx.h"
#include <WinSock2.h>
#include <winsock.h>

#pragma comment(lib, "Ws2_32.lib")

using namespace std;

void cmdError(string e = ""){
    cout << "Error:\n" << e << endl;
    chrono::milliseconds t( 3000 );
    this_thread::sleep_for( t );
}

void startServer(int port){
    SOCKET acceptSocket;
    SOCKET connectedSocket;
    SOCKADDR_IN addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=ADDR_ANY;
    memset(&addr, 0, sizeof(SOCKADDR_IN));
    long rc;
    acceptSocket = socket(AF_INET, SOCK_STREAM, 0);
    if(acceptSocket = INVALID_SOCKET){ throw new exception();}
    rc = ::bind(acceptSocket, (SOCKADDR*) &addr, sizeof(SOCKADDR_IN));
    if(rc == SOCKET_ERROR){ throw new exception();}
    rc = listen(acceptSocket, 10);
    if(rc == SOCKET_ERROR){ throw new exception();}
    connectedSocket = accept(acceptSocket, NULL, NULL);
    if(connectedSocket == INVALID_SOCKET){ throw new exception();}
}

void startClient(string ip, int port){
    long rc;
    SOCKADDR_IN addr;
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    if(s == INVALID_SOCKET){ throw new exception();}

    memset(&addr, 0, sizeof(SOCKADDR_IN));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    rc = connect(s, (SOCKADDR*)&addr, sizeof(SOCKADDR));

    if(s == SOCKET_ERROR){ throw new exception();}
}

int _tmain(int argc, _TCHAR* argv[]){
    WSADATA wsa;
    if(WSAStartup(MAKEWORD(2, 0), &wsa) != 0){
        cmdError();
        return 1;
    }
    string n;
    int port;
    cout << "Please specify the task of this thread. \nEnter 'server' or 'client'." << endl;
    getline(cin, n);
    system("cls");
    cout << "Please specify a port." << endl;
    cin.clear();
    cin.sync();
    cin >> port;
    system("cls");
    if(n.at(0) == 'c' || n.at(0) == 'C'){
        string ip;
        cout << "You started a client application." << endl;
        cout << "Enter the IP address of the server you want to connect to." << endl;
        cin.clear();
        cin.sync();
        getline(cin, ip);
        system("cls");
        cmdError();
        try{
            startClient(ip, port);
        }
        catch(exception e){
            cmdError();
            e.~exception();
            return 1;
        }

        return 0;
    }
    else if(n.at(0) == 's' || n.at(0) == 'S'){
        cout << "You started a server application" << endl;
        try {
            startServer(port);
        }
        catch(exception e){
            e.~exception();
            return 1;
        }
        return 0;
    }
    cmdError();
    return 1;
}

void sendStr(string msg){
}

When I start my server through the application I get the following error popup in void startServer(int port).

First-chance exception at 0x7667C42D in test.exe: Microsoft C++ exception:
std::exception at memory location 0x001EF5C8.

If there is a handler for this exception, the progrram may be safely continued.

Any idea why this is happening?

000000000000000000000
  • 1,467
  • 1
  • 19
  • 38

1 Answers1

1

You're not catching what you're throwing. You're throwing an exception * and you're trying to catch an exception.

You should almost never throw a new exception, you should just throw an exception, you should then catch a const reference to said exception, so for example:

#include <exception>
#include <iostream>

int
x(int y)
{
    throw std::exception();
}

int
main(int argc, char **argv)
{
    try {
        x(2);
    } catch (const std::exception &e) {
        std::cout << "Oops" << std::endl;
    }
    return 0;
}

If I used your code I get the program terminated due to an uncaught exception of type std::exception * (note that it's a pointer to std::exception, not a std::exception.

In addition, I have no idea what you're trying to accomplish with the e.~exception();. It has no place in that code. If you were trying to delete the exception that you had newd, then you should delete it. Explicit calls to destructors like this indicates that you're having difficulties understanding the object lifecycle; which is a fundamental part of the C++ language.

Charles Bailey's answer to this question goes into some detail on the whys and whats of this also.

Community
  • 1
  • 1
Anya Shenanigans
  • 91,618
  • 3
  • 107
  • 122
  • 1
    Upticked. And for the OP, note the *removal* of `e.~exception();`, which has no earthly business being there no matter what. – WhozCraig Feb 16 '15 at 08:34
  • OK - I edited my code and changed what you suggested. I still get the same error though and as I said...I'm new to cpp so pls don't judge a student. – 000000000000000000000 Feb 16 '15 at 09:41
  • so you `throw exception();` and `catch (const exception &e)` and removed the `e.~exception();`? You're always going to fail your if conditions because you're using an assignment (single `=`) within the if, instead of the test `==`. So code like: `if (acceptSocket = INVALID_SOCKET)` won't test the value of acceptSocket, it will assign the value INVALID_SOCKET to it. If you ramp up compilation warnings to 4 - `/W4`, it would have said `assignment within conditional expression`. – Anya Shenanigans Feb 16 '15 at 10:20
  • Also, the `memset` is after assigning some values, which clears them - you need to `memset` first, then assign values to the struct. Finally, if you're going to throw an `exception`, throw one with a string value so you know **where** the exception comes from. – Anya Shenanigans Feb 16 '15 at 10:27
  • Thank you - that last thing did it – 000000000000000000000 Feb 16 '15 at 12:10