我尝试运行我的 C++ 代码并尝试调试过去 1 小时。我一直在检查,但不确定我做错了什么?
如果我输入了错误的用户/密码,则代码不会有问题,但如果我正确输入了 logincheck=actionvalue,它将抛出如下所示的错误。
这是我的数据库选择语句的外观:
root@ubuntu:/home/baoky/version1.2/Assignment 2# sqlite3 abeserver.db
SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from abe_account;
admin|Peter John|admin|password
if (logincheck==actionvalue)
我的代码.cpp
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <vector>
#include <string>
#include <fstream>
#include <sqlite3.h>
#define DEFAULT_PROTOCOL 0
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#ifndef PF_LOCAL
#define PF_LOCAL PF_UNIX
#endif
//g++ -o test test.cpp -lsqlite3 (sample compile with sqlite3)
using namespace std;
/* THIS IS SERVER CODE */
/* I WILL USE A TEMP FILE account.txt for basic login auth check */
int readLine (int fd, char* str)
{
int n;
do /* Read characters until NULL or end-of-input */
{
// ssize_t read (int fd, void *buf, size_t count);
// if successful, read will:
// a) stores data read into 'buf', and
// b) returns the no. of bytes read
// read returns zero if it reaches end-of-input
n = read (fd, str, 1); /* Read one character */
}
while (n > 0 && *str++ != 0);
return (n > 0); /* Return false if end-of-input */
}
string readClient (int fd)
{
char str[2000];
while (readLine (fd, str)) /* Read lines until end-of-input */
return(string)str; /* return as string */
}
std::vector<std::string> split(std::string const& str, std::string const& delimiters = "#") {
std::vector<std::string> tokens;
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos) {
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
return tokens;
}
std::vector<std::string> split(std::string const& str, char const delimiter) {
return split(str,std::string(1,delimiter));
}
int main()
{
int serverFd;
int clientFd;
int serverLen;
int clientLen;
int counter;
string action;
string actionvalue;
string receiveClient;
string sendClient;
string department;
string sline;
string logincheck;
ifstream myfile;
struct sockaddr* serverSockAddrPtr;
struct sockaddr* clientSockAddrPtr;
struct sockaddr_un serverAddress;
struct sockaddr_un clientAddress;
//for handle zombie
//to ignore SIGCHLD(death of child signal).The zombies will not be seen.
signal(SIGCHLD, SIG_IGN);
//zombies(defunct processes ps command in Linux will show defunct entries)
cout << "" << endl;
cout << "Running server program 'ABEServer' ...... " << endl;
cout << "" << endl;
// SOCKET CREATION PART - SERVER
serverFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL);
/* Set domain type */
serverAddress.sun_family = AF_LOCAL;
/* Set name */
strcpy (serverAddress.sun_path, "ABEServer");
/* GET SIZE OF Server Addres */
serverLen = sizeof serverAddress;
/* GET SIZE OF Client Addres */
clientLen = sizeof clientAddress;
/* Get Server Sock Address Pointer*/
serverSockAddrPtr = (struct sockaddr *) &serverAddress;
/* Get Client Sock Address Pointer*/
clientSockAddrPtr = (struct sockaddr *) &clientAddress;
/* Create file */
unlink("ABEServer");
bind (serverFd, serverSockAddrPtr , serverLen);
/* listen for connection */
listen (serverFd,5);
cout << "Server started";
cout << "" << endl;
// SOCKET CREATION END - SERVER
while (1) /* Loop forever */
{
/* Accept a client connection */
clientFd = accept (serverFd, clientSockAddrPtr, (socklen_t*) &clientLen);
if (fork () == 0) /* Create child to send client */
{
while(1)
{
sendClient = "";
//read client input
receiveClient = readClient(clientFd);
vector<string> x = split(receiveClient, '#');
action = x[0];
actionvalue = x[1];
if(action=="auth")
{
logincheck = "";
counter = 0;
department = "";
//default sendClient value
sendClient = "fail login#Invalid username/password.";
sqlite3 *db;
sqlite3_stmt * stmt;
std::vector< std::vector < std:: string > > result;
for( int i = 0; i < 4; i++ )
result.push_back(std::vector< std::string >());
if (sqlite3_open("abeserver.db", &db) == SQLITE_OK)
{
sqlite3_prepare( db, "SELECT * from abe_account;", -1, &stmt, NULL );//preparing the statement
sqlite3_step( stmt );//executing the statement
while( sqlite3_column_text( stmt, 0 ) )
{
for( int i = 0; i < 4; i++ )
result[i].push_back( std::string( (char *)sqlite3_column_text( stmt, i ) ) );
sqlite3_step( stmt );
counter++;
}
//close connection to db and finalize sql statement
sqlite3_finalize(stmt);
sqlite3_close(db);
//username:password // using first record to check
for ( int i = 0; i < counter; i ++)
{
//result[column][row]
logincheck = result[0][i] + ":" + result[3][i];
department = result[2][i];
}
if (logincheck==actionvalue)
{
//send back in format of login done, login message, department level
sendClient = "login done#Successfully Login";
break;
}
result.clear();
}
}//end if auth
write (clientFd, sendClient.c_str(), strlen (sendClient.c_str()) + 1);
}//end while
}//end if fork
else
{
close (clientFd); /* Close the client descriptor */
}//end else
}//end while outer
return 0;
}
错误信息:
Username > admin
Password > password
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Segmentation fault (core dumped)