網(wǎng)站首頁 編程語言 正文
1. 讀取文件類
- 頭文件 config.h
#ifndef __CONFIG_H_
#define __CONFIG_H_
#include <map>
#include <iostream>
#include <string>
#include <fstream>
//定義配置文件注釋符號(hào)
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);
//是否空格或者tab鍵
bool is_space_or_tab(char c);
//配置文件路徑
const string config_file_path = "./conf/server.conf";
};
#endif //! __CONFIG_H_
- 源文件: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;
// for (itr = maps.begin(); itr != maps.end(); ++itr) {
// cout << itr->first <<"="<< itr->second << endl;;
// }
//socket ip
iter = maps.find("server_ip");
string server_ip;
if (iter != maps.end()) {
server_ip = iter->second;
//判斷ip是否為合法ipv4
if (inet_addr(server_ip.c_str()) == -1) {
cout << "\e[0;31mserver_host error:\e[0m ipv4 syntax error" << endl;
return;
}
}
//socket 端口
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());
//init_server.init_socket();
}
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;
}
}
//cout << "success" << endl;
infile.close();
return true;
}
//cout << "open file error: " << __FILE__ << " \nerror Function: " << __FUNCTION__ << "\nerror row: " << __LINE__ << endl\e[0;31m ;
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;
//是否存在注釋號(hào) '#'
pos = line_str.find(COMMENT_CHAR);
if (pos != string::npos) {
if (0 == pos) { //行的第一個(gè)字符就是注釋字符
return false;
}
//end_pos截止到‘#號(hào),后面為注釋’
end_pos = pos - 1;
}
//預(yù)處理,刪除注釋部分
string new_line = line_str.substr(start_pos, start_pos + 1 - end_pos);
pos = new_line.find('=');
if (pos == string::npos)
return false; //沒有 = 等號(hào)
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();
//判斷初始化成功---接收請(qǐng)求
if (success == init_status) {
perror("start...\e[0;32m");
cout << "\e[0m" << endl;
server_accept();
}
}
Tcp_server::~Tcp_server()
{
}
int Tcp_server::init_socket()
{
//創(chuàng)建套接字
s_sock = socket(AF_INET, SOCK_STREAM, 0);
if (s_sock == fail) {
perror("\e[0;31mcreate socket error!!!\e[0m") /*__TIME__ << __LINE__ << std::endl;*/;
return fail;
}
//設(shè)置套接字
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;
}
//綁定端口號(hào)
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) /*INADDR_ANY*/;
}
else {
addr.sin_addr.s_addr = INADDR_ANY /*INADDR_ANY*/;
}
if (bind(s_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("\e[0;31mbind error\e[0m");
//std::cout << "bind() error "<< __LINE__ << std::endl;
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() {
//接收請(qǐng)求
//接受客戶機(jī)連接
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;
}
//進(jìn)入fork處理接收信息
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;
//關(guān)閉連接
if (close(conn) == -1) {
perror("close client connection error:");
}
if (close(pid) == -1) {
perror("close fork error:");
}
return reject;
}
//關(guān)閉連接
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;
}
}
}
原文鏈接:https://blog.csdn.net/weixin_41560737/article/details/126579179
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-09-07 python?sklearn?畫出決策樹并保存為PDF的實(shí)現(xiàn)過程_python
- 2022-09-18 Python動(dòng)態(tài)配置管理Dynaconf的實(shí)現(xiàn)示例詳解_python
- 2022-08-27 關(guān)于pygame自定義窗口創(chuàng)建及相關(guān)操作指南_python
- 2022-06-29 python中py文件與pyc文件相互轉(zhuǎn)換的方法實(shí)例_python
- 2022-12-02 C語言實(shí)現(xiàn)動(dòng)態(tài)順序表的示例代碼_C 語言
- 2024-02-17 通過springMVC統(tǒng)一設(shè)置localhost的時(shí)間格式
- 2022-03-31 C語言16進(jìn)制與ASCII字符相互轉(zhuǎn)換_C 語言
- 2022-11-24 Django?ORM?F對(duì)象和Q對(duì)象查詢_python
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支