代码之家  ›  专栏  ›  技术社区  ›  000000000000000000000

std::启动服务器时发生异常(WinSock2)

  •  0
  • 000000000000000000000  · 技术社区  · 9 年前


    我是C++新手,目前正在从 tutorial 如何使用winsock(2)。
    然而,我的服务器遇到了问题。我不知道这是怎么发生的。

    #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){
    }
    

    当我通过应用程序启动服务器时 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.
    

    知道为什么会这样吗?

    1 回复  |  直到 9 年前
        1
  •  1
  •   Community miroxlav    7 年前

    你没有接住你扔的东西。你在扔一个 exception * 你想抓住一个 exception .

    你几乎不应该扔 new 异常,您应该只抛出一个异常,然后应该捕获对所述异常的常量引用,例如:

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

    如果我使用了你的代码,我会因为一个未捕获的异常类型而终止程序 std::exception * (注意,它是指向 std::exception ,不是 std::异常 .

    此外,我不知道你想用 e.~exception(); 。它在该代码中没有位置。如果您试图删除您的异常 d、 那么你应该 delete 像这样对析构函数的显式调用表明您很难理解对象生命周期;这是 C++ 语言

    查尔斯·贝利的 answer to this question 也会详细说明为什么会这样。