客户端代码在通过winsock API连接到C ++服务器时突然中止

时间:2017-09-09 09:51:07

标签: c++ winsock

最近我正在制作能够连接多个客户端的多线程服务器应用程序。但是,当我运行客户端应用程序时,一些运行时库异常发生在" Debug Assertion Failed"对话。我无法找出此错误的确切原因。我在Visual Studio Ultimate 2013中使用了Winsock API。有人可以请我帮忙寻找解决方案吗?任何帮助将不胜感激!

客户端:

#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <iostream>
#include <signal.h>
#include <stdio.h>

using namespace std;

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

//DECLARATIONS
//error trapping signals
#define SIGINT 2
#define SIGKILL 9
#define SIGQUIT 3
// SOCKETS
SOCKET sock, client;

void s_handle(int s)
{
    if (sock)
        closesocket(sock);
    if (client)
        closesocket(client);
    WSACleanup();
    Sleep(10);
    cout << "EXIT SIGNAL :" << s;
    exit(0);
}


void s_cl(char *a, int x)
{
    cout << a;
    s_handle(x + 1000);
}


int main()
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    //SetConsoleTitle(".:: Basic Echo Client By KOrUPt 07 ::. ");


    //Declarations
    DWORD poll;
    int res, i = 1, port = 999;
    char buf[100];
    char msg[100] = "";
    char ip[15];
    WSADATA data;

    signal(SIGINT, s_handle);
    signal(SIGKILL, s_handle);
    signal(SIGQUIT, s_handle);

    cout << "\t\tEcho This is a Client";

    cout << "\n\n\n\t\tEnter IP to connect to: ";
    gets(ip);

    sockaddr_in ser;
    sockaddr addr;


    ser.sin_family = AF_INET;
    ser.sin_port = htons(123);                    //Set the port
    ser.sin_addr.s_addr = inet_addr(ip);      //Set the address we want to connect to

    memcpy(&addr, &ser, sizeof(SOCKADDR_IN));

    res = WSAStartup(MAKEWORD(1, 1), &data);      //Start Winsock
    cout << "\n\nWSAStartup"
        << "\nVersion: " << data.wVersion
        << "\nDescription: " << data.szDescription
        << "\nStatus: " << data.szSystemStatus << endl;

    if (res != 0)
        s_cl("WSAStarup failed", WSAGetLastError());

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);       //Create the socket
    if (sock == INVALID_SOCKET)
        s_cl("Invalid Socket ", WSAGetLastError());
    else if (sock == SOCKET_ERROR)
        s_cl("Socket Error)", WSAGetLastError());
    else
        cout << "Socket Established" << endl;



    res = connect(sock, &addr, sizeof(addr));               //Connect to the server
    if (res != 0)
    {
        s_cl("SERVER UNAVAILABLE", res);
    }
    else
    {
        cout << "\nConnected to Server: ";
        memcpy(&ser, &addr, sizeof(SOCKADDR));
    }

    char RecvdData[100] = "";
    int ret;

    while (true)
    {
        strcpy(buf, "");
        cout << "\nEnter message to send ->\n";
        fgets(buf, sizeof(buf), stdin);


        Sleep(5);
        res = send(sock, buf, sizeof(buf), 0);

        if (res == 0)
        {
            //0==other side terminated conn
            printf("\nSERVER terminated connection\n");
            Sleep(40);
            closesocket(client);
            client = 0;
            break;
        }
        else if (res == SOCKET_ERROR)
        {
            //-1 == send error
            printf("Socket error\n");
            Sleep(40);
            s_handle(res);
            break;
        }

        ret = recv(sock, RecvdData, sizeof(RecvdData), 0);
        if (ret > 0)
        {
            cout << endl << RecvdData;
            strcpy(RecvdData, "");
        }
    }

    closesocket(client);
    WSACleanup();
}

服务器:

#include <windows.h>
#include  <stdlib.h>
#include <stdio.h>
#include <winsock.h>
#include <iostream>

using namespace std;

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

// our thread for recving commands
DWORD WINAPI receive_cmds(LPVOID lpParam)
{
    cout << "thread created\r\n";

    // set our socket to the socket passed in as a parameter   
    SOCKET current_client = (SOCKET)lpParam;

    // buffer to hold our recived data
    char buf[100];
    // buffer to hold our sent data
    char sendData[100];
    // for error checking 
    int res;

    // our recv loop
    while (true)
    {
        res = recv(current_client, buf, sizeof(buf), 0); // recv cmds

        Sleep(2);

        if (res == 0)
        {
            //MessageBox(0, "error", "error", MB_OK);
            closesocket(current_client);
            ExitThread(0);
        }

        if (strstr(buf, "hello"))
        { // greet this user
            cout << "\nrecived hello cmd";

            strcpy(sendData, "hello, greetings from server\n");
            Sleep(2);
            send(current_client, sendData, sizeof(sendData), 0);
        }
        else if (strstr(buf, "bye"))
        { // dissconnected this user
            cout << "\nrecived bye cmd\n";

            strcpy(sendData, "cya\n");
            Sleep(2);
            send(current_client, sendData, sizeof(sendData), 0);

            // close the socket associted with this client and end this thread
            closesocket(current_client);
            ExitThread(0);
        }
        else
        {
            strcpy(sendData, "Invalid cmd\n");
            Sleep(2);
            send(current_client, sendData, sizeof(sendData), 0);
        }

        // clear buffers
        strcpy(sendData, "");
        strcpy(buf, "");
    }
}

int main()
{
    printf("Starting up multi-threaded TCP server");

    // our masterSocket(socket that listens for connections)
    SOCKET sock;

    // for our thread
    DWORD thread;

    WSADATA wsaData;
    sockaddr_in server;

    // start winsock
    int ret = WSAStartup(0x101, &wsaData); // use highest version of winsock avalible

    if (ret != 0)
    {
        return 0;
    }

    // fill in winsock struct ... 
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(123); // listen on telnet port 23

    // create our socket
    sock = socket(AF_INET, SOCK_STREAM, 0);

    if (sock == INVALID_SOCKET)
    {
        return 0;
    }

    // bind our socket to a port(port 123) 
    if (bind(sock, (sockaddr*)&server, sizeof(server)) != 0)
    {
        return 0;
    }

    // listen for a connection  
    if (listen(sock, 5) != 0)
    {
        return 0;
    }

    // socket that we sendrecv data on
    SOCKET client;

    sockaddr_in from;
    int fromlen = sizeof(from);

    // loop forever 
    while (true)
    {
        // accept connections
        client = accept(sock, (struct sockaddr*)&from, &fromlen);
        cout << "Client connected\r\n";

        // create our recv_cmds thread and parse client socket as a parameter
        CreateThread(NULL, 0, receive_cmds, (LPVOID)client, 0, &thread);
    }

    // shutdown winsock
    closesocket(sock);
    WSACleanup();

    // exit
    return 0;
}

0 个答案:

没有答案