1. 读取文件类
- 头文件 config.h
#ifndef __CONFIG_H_
#define __CONFIG_H_
#include <map>
#include <iostream>
#include <string>
#include <fstream>
constexpr auto COMMENT_CHAR = '#';
using namespace std;
class Config_handle {
public:
Config_handle();
~Config_handle();
private:
bool read_config_file(const string& filename, map<string, string>& m);
bool analyse_line(const string& line, string& key, string& value);
void trim_str(string& str);
bool is_space_or_tab(char c);
const string config_file_path = "./conf/server.conf";
};
#endif
- 源文件:config.cpp
#include "config.h"
#include "server.h"
Config_handle::~Config_handle()
{
}
Config_handle::Config_handle()
{
map<string, string>maps;
read_config_file(config_file_path, maps);
map<string, string>::iterator iter;
iter = maps.find("server_ip");
string server_ip;
if (iter != maps.end()) {
server_ip = iter->second;
if (inet_addr(server_ip.c_str()) == -1) {
cout << "\e[0;31mserver_host error:\e[0m ipv4 syntax error" << endl;
return;
}
}
string port;
iter = maps.find("port");
if (iter != maps.end()) {
port = iter->second;
for (int i = 0; i < port.length(); i++) {
if (!(isdigit(port[i]))) {
cout << "\e[0;31mserver_port error:\e[0m port not support!" << endl;
return;
}
}
if (0 <(atoi(port.c_str())) && (atoi(port.c_str())) < 65535) {
Tcp_server init_server = Tcp_server(server_ip.c_str(), port.c_str());
}
else {
cout << "\e[0;31mserver port error:\e[0m value range 0-65535 " << endl;;
return;
}
}
}
bool Config_handle::read_config_file(const string& filename, map<string, string>& m)
{
m.clear();
ifstream infile(filename.c_str());
if (infile.is_open()) {
string line_str, key, value;
while (getline(infile, line_str)) {
if (analyse_line(line_str,key,value)) {
m[key] = value;
}
}
infile.close();
return true;
}
perror("\e[0;31mopen server.conf error:\e[0m");
infile.close();
return false;
}
bool Config_handle::analyse_line(const string& line_str, string& key, string& value)
{
if (line_str.empty())
return false;
int start_pos = 0, end_pos = line_str.size() - 1, pos;
pos = line_str.find(COMMENT_CHAR);
if (pos != string::npos) {
if (0 == pos) {
return false;
}
end_pos = pos - 1;
}
string new_line = line_str.substr(start_pos, start_pos + 1 - end_pos);
pos = new_line.find('=');
if (pos == string::npos)
return false;
key = new_line.substr(0, pos);
value = new_line.substr(pos + 1, end_pos + 1 - (pos + 1));
trim_str(key);
if (key.empty()) {
return false;
}
trim_str(value);
return true;
}
void Config_handle::trim_str(string& str)
{
if (str.empty()) {
return;
}
int i, start_pos, end_pos;
for (i = 0; i < str.size(); ++i) {
if (!is_space_or_tab(str[i])) {
break;
}
}
if (i == str.size()) {
str = "";
return;
}
start_pos = i;
for (i = str.size() - 1; i >= 0; --i) {
if (!is_space_or_tab(str[i])) {
break;
}
}
end_pos = i;
str = str.substr(start_pos, end_pos - start_pos + 1);
}
bool Config_handle::is_space_or_tab(char c)
{
if (' ' == c || '\t' == c)
return true;
return false;
}
2. 编写TCP socket
- 头文件server.h
#ifndef __SERVER_H_
#define __SERVER_H_
#include <iostream>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cctype>
#include <cstring>
#include <unistd.h>
#include "config.h"
const int reject = -2;
const int fail = -1;
const int success = 0;
class Tcp_server {
public:
Tcp_server(const char* ip, const char* port);
~Tcp_server();
int init_socket();
int server_accept();
private:
const char* server_ip;
const char* server_port;
int recv_msg(int);
};
#endif
- 源文件: server.cpp
#include "server.h"
static int s_sock = -1;
Tcp_server::Tcp_server(const char* ip, const char* port) :
server_ip(ip),
server_port(port)
{
int init_status = init_socket();
if (success == init_status) {
perror("start...\e[0;32m");
cout << "\e[0m" << endl;
server_accept();
}
}
Tcp_server::~Tcp_server()
{
}
int Tcp_server::init_socket()
{
s_sock = socket(AF_INET, SOCK_STREAM, 0);
if (s_sock == fail) {
perror("\e[0;31mcreate socket error!!!\e[0m") ;
return fail;
}
int on = 1;
int set_s = setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (set_s == -1) {
perror("setsockopt error\n");
return fail;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(server_port));
if (string(server_ip) == "127.0.0.1") {
addr.sin_addr.s_addr = inet_addr(server_ip) ;
}
else {
addr.sin_addr.s_addr = INADDR_ANY ;
}
if (bind(s_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("\e[0;31mbind error\e[0m");
return fail;
}
if (listen(s_sock, 1024) == -1) {
std::cout << "Listen error " << __LINE__ << __FILE__ << std::endl;
return fail;
}
return success;
}
int Tcp_server::server_accept() {
for (;;) {
struct sockaddr_in addrcli = {};
socklen_t addrlen = sizeof(addrcli);
int conn = accept(s_sock, (struct sockaddr*)&addrcli, &addrlen);
if (conn == -1) {
perror("accept");
return -1;
}
std::cout << "connectioned client status: " << inet_ntoa(addrcli.sin_addr) << " " << ntohs(addrcli.sin_port) << endl;
string buf = "welcome to DJ BB!\n>";
char username[10] = "username:";
ssize_t send_msg = send(conn, buf.c_str(), buf.length(), 0);
send_msg = send(conn, username, 10, 0);
if (send_msg == -1) {
perror("send:");
return -1;
}
pid_t pid = fork();
if (pid == -1) {
perror("fork create error:");
return -1;
}
else if (pid == 0) {
if (close(s_sock) == -1) {
perror("close s_sock error: ");
return -1;
}
int recv_status = recv_msg(conn);
switch (recv_status) {
case success:
break;
case fail:
break;
case reject:
cout << "client IP reject: " << inet_ntoa(addrcli.sin_addr) << endl;
if (close(conn) == -1) {
perror("close client connection error:");
}
if (close(pid) == -1) {
perror("close fork error:");
}
return reject;
}
if (close(conn) == -1) {
perror("close client connection error:");
}
if (close(pid) == -1) {
perror("close fork error:");
}
return success;
}
}
}
int Tcp_server::recv_msg(int conn)
{
for (;;) {
char username[1024] = { 0 };
ssize_t recv_msg = recv(conn, username, sizeof(username), 0);
if (recv_msg == -1) {
perror("recv_msg error:");
close(conn);
return fail;
}
if (recv_msg == 0) {
break;
}
cout << username << endl;
if (username == "root") {
char password[10] = "password:";
cout << "equal" << endl;
cout << username;
memset(username, '\0', sizeof(username));
ssize_t send_msg = send(conn, password, 10, 0);
return success;
}
else {
memset(username, '\0', sizeof(username));
string reject_str = "Code:403, Connection closed by foreign host.";
ssize_t send_msg = send(conn, reject_str.c_str(), reject_str.length(), 0);
return reject;
}
}
}