C++ 我得到一个;“调试断言失败”;在我的TCP_客户端程序中输入用户名后出错
我目前是自动化和应用信息学专业的学生。我有一个来自计算机网络的项目,在这个项目中,我需要在线程的帮助下制作一个聊天应用程序。从现在起,我为服务器创建了连接的接收部分,并创建了客户端,但在运行程序时,我收到了一个调试断言失败错误。到目前为止,我只有用户连接部分。我真的需要一些帮助,因为我被卡住了C++ 我得到一个;“调试断言失败”;在我的TCP_客户端程序中输入用户名后出错,c++,multithreading,winapi,chat,C++,Multithreading,Winapi,Chat,我目前是自动化和应用信息学专业的学生。我有一个来自计算机网络的项目,在这个项目中,我需要在线程的帮助下制作一个聊天应用程序。从现在起,我为服务器创建了连接的接收部分,并创建了客户端,但在运行程序时,我收到了一个调试断言失败错误。到目前为止,我只有用户连接部分。我真的需要一些帮助,因为我被卡住了 tcp_server.cpp #include "winsock2.h" #include "ClientThread.h" #include <stdio
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_server.cpp
#包括“winsock2.h”
#包括“ClientThread.h”
#包括
#包括
#包括
#包括“WS2TCPP.h”
#pragma注释(lib,“ws2_32.lib”)
const unsigned int SysThread::INFINIT_WAIT=UINT_MAX;
void main()
{
WSADATA WSADATA;
int-iResult=WSAStartup(MAKEWORD(2,2)和wsaData);
如果(iResult!=无错误){
printf(“WSAStartup()错误\n”);
返回;
}
//用于侦听传入请求的套接字
SOCKET-ListenSocket;
ListenSocket=socket(AF_INET、SOCK流、IPPROTO_TCP);
if(ListenSocket==无效的_套接字){
printf(“侦听套接字出错,错误代码:%d\n”,WSAGetLastError);
WSACleanup();
返回;
}
int端口=1300;
字符IP[10]=“127.0.0.1”;
服务器地址中的sockaddr_;
int ServerLen=sizeof(服务器地址);
ServerAddress.sin_family=AF_INET;
ServerAddress.sin_port=htons(端口);
inet\u pton(AF\u inet、IP和ServerAddress.sin\u addr);
if(bind(ListenSocket,(SOCKADDR*)&ServerAddress,sizeof(ServerAddress))==SOCKET\u错误){
printf(“bind()失败。\n”);
闭合插座(ListenSocket);
WSACleanup();
返回;
}
如果(侦听(ListenSocket,1)==套接字错误){
printf(“在套接字上侦听时出错。\n”);
WSACleanup();
返回;
}
std::向量用户名;
int RecUserLen=100;
字符重现器[100];
int ReceiveTheUsername;
//用于接受传入请求的套接字
插座接受插座;
printf(“正在等待客户端连接…\n”);
while(AcceptSocket=accept(ListenSocket,NULL,NULL)){
printf(“成功连接。\n”);
int UserNum=1;
ReceiveTheUsername=recv(AcceptSocket,RecUser,RecUser-1,0);
username[UserNum]=重现器;
printf(“用户名:%s”,用户名[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;
}
#包括
#包括
#包括
#包括“winsock2.h”
#包括“WS2TCPP.h”
#pragma注释(lib,“ws2_32.lib”)
void main()
{
国际结果;
//----------------------
WSADATA WSADATA;
iResult=WSAStartup(MAKEWORD(2,2)和wsaData);
如果(iResult!=无错误)
printf(“Hiba a WSAStartup()–nál\n”);
//----------------------
插座客户端插座;
ClientSocket=socket(AF\u INET、SOCK\u STREAM、IPPROTO\u TCP);
if(ClientSocket==无效的_SOCKET)
{
printf(“初始化套接字时出错,错误代码:%ld\n”,
WSAGetLastError());
WSACleanup();
返回;
}
//---------------------
int端口=1300;
字符IP[10]=“127.0.0.1”;
服务器addr中的sockaddr_;
int AddrLen=sizeof(ServerAddr);
ServerAddr.sin_family=AF_INET;
inet\u pton(AF\u inet,“127.0.0.1”和ServerAddr.sin\u addr);
ServerAddr.sinu端口=htons(端口);
//----------------------
if(connect(ClientSocket,(SOCKADDR*)&ServerAddr,AddrLen)==SOCKET\u错误)
{
printf(“连接错误,错误代码:%ld\n”,
WSAGetLastError());
WSACleanup();
返回;
}
否则{
printf(“成功连接。\n”);
}
//----------------------
字符用户名[100];
printf(“输入用户名:”);
fgets(用户名,100,标准输入);
int-SendUsername;
SendUsername=send(ClientSocket,Felhasznalonev,sizeof(Felhasznalonev),0);
if(SendUsername==SOCKET\u错误){
printf(“发送用户名时出错。\n”);
闭合插座(ClientSocket);
WSACleanup();
返回;
}
闭合插座(ClientSocket);
WSACleanup();
返回;
}
这里有一个明显的问题
std::vector <char*> username;
...
int UserNum = 1;
...
username[UserNum] = RecUser;
std::vector用户名;
...
int UserNum=1;
...
username[UserNum]=重现器;
username
是一个零大小的向量,因此username[UserNum]
是一个越界向量访问
不太清楚为什么要使用向量,它没有像现在这样向代码中添加任何内容。但是如果您确实需要使用一个,那么请确保它足够大。调试断言失败错误的原因正如John所说,您没有设置
向量用户名的大小,因此无法通过赋值直接设置向量中的值
但输出乱码字符的原因是,读取的字节数超过了实际返回的字节数
根据报告:
返回值
如果没有发生错误,recv返回接收到的字节数,buf参数指向的缓冲区将包含接收到的数据。如果连接已正常关闭,则返回值为零
否则,将返回SOCKET_ERROR的值,并且可以通过调用
因此,recv
函数的返回值(在代码中是ReceiveTheUsername
)实际上是实际读取的字节数,而不是receiserlen-1
,因此您可以使用ReceiveTheUsername
来确定返回字符串长度的有效性
您只需要像下面的代码一样将字符串初始化为空,就可以防止乱码。(当然,您也可以根据返回的字符数手动添加'\0',或者根据字符长度截取相应的字符串。)
如果这是Visual Studio,请在失败的断言上插入调试器,并将堆栈帧切换到代码。查看断言失败时正在执行的代码行。
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());
}