簡體   English   中英

在我的 TCP_Client 程序中輸入用戶名后,出現“調試斷言失敗”錯誤

[英]I get a "Debug assertion failed" error after entering the username in my TCP_Client program

我目前是自動化和應用信息學專業的學生。 我有一個來自計算機網絡的項目,我需要在線程的幫助下制作一個聊天應用程序。 從現在開始,我為服務器創建了連接的接收部分並創建了客戶端,但是當我運行程序時出現調試斷言失敗錯誤。 到目前為止,我只有用戶連接部分。 我真的需要一些幫助,因為我被困住了。

tcp_server.cpp

#include "winsock2.h"
#include "ClientThread.h"
#include <stdio.h>
#include <string.h>
#include <vector>
#include "ws2tcpip.h"
#pragma comment(lib,"ws2_32.lib")

const unsigned int SysThread::INFINIT_WAIT = UINT_MAX;

void main()
{
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        printf("Error at WSAStartup()\n");
        return;
    }

    // Socket for listening for incoming requests
    SOCKET ListenSocket;
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        printf("Error at the listening socket, error code: %d\n", WSAGetLastError);
        WSACleanup();
        return;
    }

    int Port = 1300;
    char IP[10] = "127.0.0.1";
    sockaddr_in ServerAddress;
    int ServerLen = sizeof(ServerAddress);

    ServerAddress.sin_family = AF_INET;
    ServerAddress.sin_port = htons(Port);
    inet_pton(AF_INET, IP, &ServerAddress.sin_addr);

    if (bind(ListenSocket, (SOCKADDR*)&ServerAddress, sizeof(ServerAddress)) == SOCKET_ERROR) {
        printf("bind() failed.\n");
        closesocket(ListenSocket);
        WSACleanup();
        return;
    }

    if (listen(ListenSocket, 1) == SOCKET_ERROR) {
        printf("Error listening on socket.\n");
        WSACleanup();
        return;
    }

    std::vector <char*> username;
    int RecUserLen = 100;
    char RecUser[100];
    int ReceiveTheUsername;

    // Socket for accepting incoming requests
    SOCKET AcceptSocket;
    printf("Waiting for client to connect...\n");

    while (AcceptSocket = accept(ListenSocket, NULL, NULL)) {
        printf("Succesful connection.\n");
        int UserNum = 1;
        ReceiveTheUsername = recv(AcceptSocket, RecUser, RecUserLen-1, 0);
        username[UserNum] = RecUser;
        printf("Username: %s", username[UserNum]);
    }
}

tcp_client.cpp

#include <iostream>
#include <stdio.h>
#include <string.h>
#include "winsock2.h"
#include "ws2tcpip.h"
#pragma comment(lib, "ws2_32.lib")
void main()
{
    int iResult;
    //----------------------
    WSADATA wsaData;
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR)
        printf("Hiba a WSAStartup() –nál\n");
    //----------------------

    SOCKET ClientSocket;
    ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (ClientSocket == INVALID_SOCKET)
    {
        printf("Error at initializing the socket, error code: %ld\n",
            WSAGetLastError());
        WSACleanup();
        return;
    }
    //---------------------
    int Port = 1300;
    char IP[10] = "127.0.0.1";
    sockaddr_in ServerAddr;
    int AddrLen = sizeof(ServerAddr);

    ServerAddr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &ServerAddr.sin_addr);
    ServerAddr.sin_port = htons(Port);
    //----------------------
   
    if (connect(ClientSocket, (SOCKADDR*)&ServerAddr, AddrLen) == SOCKET_ERROR)
    {
        printf("Connect error, error code: %ld\n",
            WSAGetLastError());
        WSACleanup();
        return;
    }
    else {
        printf("Succesful connection.\n");
    }
    //----------------------

    char UserName[100];
    printf("Enter the username: ");
    fgets(UserName, 100, stdin);

    int SendUsername;
    SendUsername = send(ClientSocket, Felhasznalonev, sizeof(Felhasznalonev),0);
    if (SendUsername == SOCKET_ERROR) {
        printf("Error at sending the username.\n");
        closesocket(ClientSocket);
        WSACleanup();
        return;
    }

    closesocket(ClientSocket);
    WSACleanup();
    return;
}

那么這里有一個明顯的問題

std::vector <char*> username;
...
int UserNum = 1;
...
username[UserNum] = RecUser;

username是一個零大小的向量,所以username[UserNum]是一個越界向量訪問。

不太確定為什么要使用向量,它不會像當前那樣向代碼中添加任何內容。 但是,如果您確實需要使用一個,請確保它足夠大。

debug assertion failed 錯誤的原因正如John所說,你沒有設置vector <char*> username的大小,所以你不能通過賦值直接設置vector中的值。

但是你output亂碼的原因是你讀取的字節數超過了實際返回的字節數。

根據文件

返回值 如果沒有錯誤發生,recv 返回接收到的字節數,buf 參數指向的緩沖區將包含接收到的數據。 如果連接已正常關閉,則返回值為零。

否則,返回一個 SOCKET_ERROR 的值,並且可以通過調用檢索特定的錯誤代碼

所以recv function(代碼中為ReceiveTheUsername )的返回值實際上是實際讀取的字節數,而不是RecUserLen-1 ,所以可以通過ReceiveTheUsername判斷返回字符串長度的合法性。

只需要像下面的代碼一樣把字符串初始化為空,就可以防止亂碼。(當然你也可以根據返回的字符數手動加上'\0',或者根據字符長度。)

char RecUser[100] = "";
while (AcceptSocket = accept(ListenSocket, NULL, NULL)) {
    printf("Succesful connection.\n");
    ReceiveTheUsername = recv(AcceptSocket, RecUser, RecUserLen - 1, 0);
    username.push_back(RecUser);
    printf("Username: %s", username.back());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM