C++模拟多线程的ATM自动取款机

一、简介

1、项目环境:Linux Ubuntu 16.04操作系统、C/C++语言
2、开发工具:Vim编辑器、g++4.8编译器、Makefile脚本、mysql数据库
3、技术关键:C++面向对象设计思想、基于TCP协议的网络编程技术、线程池技术
4、项目描述:项目基于Linux操作系统实现,采用C/S模式,使用TCP协议模拟ATM终端与服务器的通信过程。同时,本项目还在Server端创建了固定数量的线程池,用以减小创建线程时的开销,应对突发性大量请求。

二、项目目录结构

在这里插入图片描述

三、数据库设计

card.sql

create database card;

use card;

create table card_info(
	_id_num char(20) primary key not null, 
	_name char(20) not null, 
	_card_num char(20), 
	_pswd char(8), 
	_money bigint
);

四、代码设计

myalgorithm.hpp

#pragma once

#include<string>
#include<vector>

vector<string> split_string(string str)
{
   
	vector<string> ret;
	string s;
	for(int i = 2; i < str.size(); i++)
	{
   
		if(str[i] == ' ')
		{
   
			ret.push_back(s);
			s.clear();
		}
		else
		{
   
			s += str[i];
			if(i == str.size() - 1)
			{
   
				ret.push_back(s);
			}
		}
	}
	return ret;
}

tcp_socket.hpp

#pragma once

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<string>
#include<cassert>
#include<unistd.h>

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>

typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;

#define CHECK_RET(exp) if(!(exp)){return false;}

class tcp_socket
{
   
private:
	int _fd;
public:
	tcp_socket():_fd(-1)
	{
   }

	tcp_socket(int fd):_fd(fd)
	{
   }

	bool _socket()
	{
   
		_fd = socket(AF_INET, SOCK_STREAM, 0);
		if(_fd < 0)
		{
   
			perror("socket");
			return false;
		}
		return true;
	}

	bool _close() const
	{
   
		close(_fd);
		return true;
	}

	bool _bind(const std::string& ip, uint16_t port) const
	{
   
		sockaddr_in addr;
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = inet_addr(ip.c_str());
		addr.sin_port = htons(port);

		int ret = bind(_fd, (sockaddr *)&addr, sizeof(addr));
		if(ret < 0)
		{
   
			perror("bind");
			return false;
		}
		return true;
	}

	bool _listen(int num) const
	{
   
		int ret = listen(_fd, num);
		if(ret < 0)
		{
   
			perror("listen");
			return false;
		}
		return true;
	}

	bool _accept(tcp_socket *peer, std::string *ip = nullptr, uint16_t *port = nullptr) const
	{
   
		sockaddr_in peer_addr;
		socklen_t len = sizeof(peer_addr);
		int new_sock = accept(_fd, (sockaddr *)&peer_addr, &len);
		if(new_sock < 0)
		{
   
			perror("accept");
			return false;
		}
		peer->_fd = new_sock;
		if(ip != nullptr)
		{
   
			*ip = inet_ntoa(peer_addr.sin_addr);
		}
		if(port != nullptr)
		{
   
			*port = ntohs(peer_addr.sin_port);
		}
		return true;
	}

	bool _recv(std::string *buf) const
	{
   
		buf->clear();
		char tmp[1024 * 10] = {
   };
		ssize_t read_size = recv(_fd, tmp, sizeof(tmp), 0);
		if(read_size < 0)
		{
   
			perror("recv");
			return false;
		}
		if(read_size == 0)
		{
   
			return false;
		}
		buf->assign(tmp, read_size);
		return true;
	}

	bool _send(const std::string& buf) const
	{
   
		ssize_t write_size = send(_fd, buf.data(), buf.size(), 0);
		if(write_size < 0)
		{
   
			perror("send");
			return false;
		}
		return true;
	}

	bool _connect(const std::string& ip, uint16_t port) const
	{
   
		sockaddr_in addr;
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = inet_addr(ip.c_str());
		addr.sin_port = htons(port);

		int ret = connect(_fd, (sockaddr *)&addr, sizeof(addr));
		if(ret < 0)
		{
   
			perror("connect");
			return false;
		}
		return true;
	}

	int _get_fd() const
	{
   
		return _fd;
	}
};

thread_pool.hpp

#pragma once

#include"../include/tcp_socket.hpp"
#include<iostream>
#include<queue>
#include<pthread.h>
#include<unistd.h>
#include<time.h>
#include<functional>

#define MAX_THREAD 5

typedef std::function<void (const std::string& req, std::string *resp)> Handler;

struct thread_arg
{
   
	tcp_socket new_sock;
	std::string ip;
	uint16_t port;
	Handler handler;
};

typedef bool (*handler_t)(thread_arg *);

using namespace std;

class ThreadTask
{
   
private:
	thread_arg *_data;
	handler_t _handler;
public:
	ThreadTask(thread_arg *data, handler_t handler)
		:_data(data),_handler(handler)
	{
   }

	void setTask(thread_arg *data, handler_t handler)
	{
   
		_data = data;
		_handler = handler;
	}

	void run()
	{
   
		_handler(_data);
	}
};

class ThreadPool
{
   
private:
	int _thread_max;
	int _thread_cur;
	bool _tp_quit;
	queue<ThreadTask
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值