Linux下基于C++11的socket网络编程(线程版本)

第一:关于C++11的线程操作

        哈哈,百度这个比较直接,可以很清楚的告诉你。

第二:声明

        不再追溯,可以先看看(基础版本)(进程版本)(select函数版本)(epoll版本)再看这个,谢谢。

        工具类我也不再写,可以查看(进程版本),一模一样,直接复制过来就可以用了。

        客户端也和(进程版本)一样,所以后面的文章,就不再写客户端。

第三:代码

工具类:略,看声明

客户端:略,看声明

服务端

/*================================================================
*   Copyright (C) 2021 ymbLite. All rights reserved.
*   
*   文件名称:TcpServer.h
*   创 建 者:ymbLite
*   创建日期:2021年11月03日
*   描    述:socket编程中,简单的TCP服务端
*
================================================================*/


#ifndef _TCPSERVER_H
#define _TCPSERVER_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "BaseUtil.h"

const int BUFF_SIZE = 1024;	//最多可以接受的字节数
const int MAX_CLIENT = 10;	//最多允许10个客户端的同时连接

using std::cout;
using std::endl;
using std::cin;
using std::string;
using std::vector;

//自定义套接字的描述信息
struct descript_socket{
	int 	sockfd 		= -1;	//socket描述符
	string 	ip_addr 	= "";	//ip地址
	int 	id		= -1;	//sock的编号

};

class TcpServer{
	private:
		struct sockaddr_in serv_addr;	//服务器中服务端的网络地址结构
		struct sockaddr_in clnt_addr;	//服务端中客户端的网络地址结构
		socklen_t clnt_addr_len;	//服务器中客户端的网络地址结构的长度
		int m_buflen;			//调用Read方法后,读取的子接大小,单位是子接

		//关于线程的成员变量
		int socket_id = 0;		//C++11之后,可以在这里进行初始化
		std::mutex _mutex;		//互斥量
		vector _descript_socket;//保存连接的socket数据
		
	public:
		int serv_sock;			//服务器中服务端的socket描述符
		int clnt_sock;			//服务器中客户端的socket描述符

	private:
		/*
		 * 阻塞接受客户端的连接
		 * return
		 * 	-1:客户端连接失败 
		 * 	0:服务端未开启socket服务 
		 * 	>0:成功接受一个客户端的连接,返回的是客户在服务端中的socket描述符
		 * */
		int Accept();
		
		/*
		 * 回声线程
		 * */
		void EchoThread(descript_socket* _descript_socket);
	public:
		//构造函数
		TcpServer();
		//析构函数
		~TcpServer();

		/*
		 * 初始化服务器
		 * 服务端地址使用INADDR_ANY
		 * port:端口号
		 * */
		bool InitServer(const string& port);

		/*
		 * 接收客户端发送过来的数据
		 * buffer	:接受数据缓冲区的地址,数据的长度保存在m_buflen成员变量中
		 * timeout	:等待数据的超时时间,单位为秒,缺省为0-无限等待
		 *	
		 * return 	:true-成功,false-失败,失败的情况有两种,1)超时等待,2)socket连接不可用
		 * */
		bool Read( char* buffer , const int timeout  = 0);

		/*
		 * 向客户端写入数据
		 *
		 * buffer	:带发送数据的缓冲区地址
		 * ibuflen	:待发送数据的大小,单位:字节,缺省值为0,
		 * 			如果是ascii字符串,ibuflen取0
		 * 			如果是二进制数据流,那么ibuflen就取数据块的大小
		 *
		 * return	:true-成功,false-失败,失败原因为socket连接不可用
		 * */
		bool Write(const char* buffer , const int ibuflen = 0);

		/*
		 * 开始接受客户端的请求,并且创建线程
		 * */
		int StartCreateThread();

		/**
		 * 关闭服务器中服务端的套接字
		 */
		void CloseServerSock();

		/*
		 * 关闭服务器中客户端的套接字
		 * */
		void CloseClientSock();

};
#endif //TCPSERVER_H
/*================================================================
*   Copyright (C) 2021 ymbLite. All rights reserved.
*   
*   文件名称:TcpServer.cpp
*   创 建 者:ymbLite
*   创建日期:2021年11月03日
*   描    述:
*
================================================================*/


#include "TcpServer.h"

TcpServer::TcpServer():serv_sock(-1),clnt_sock(-1){
}

TcpServer::~TcpServer(){
	CloseServerSock();
}

bool TcpServer::InitServer(const string& port){

	//先判断服务端socket是否已开启
	if(serv_sock > 0){
		CloseServerSock();
		serv_sock = -1;
	}

	//创建服务器中的服务端socket
	serv_sock = socket(PF_INET , SOCK_STREAM , 0);
	if(serv_sock == -1){
		cout<<"服务器创建监听套接字失败,socket() error!"<sockfd<<"\tip_addr:"<<_descript_socket->ip_addr<<"\tid:"<<_descript_socket->id<<"]"<sockfd , msg , &msg_len)){
		msg[msg_len] = 0;
		cout<<"【"<<_descript_socket->sockfd<<"】:"<sockfd , msg)){
			cout<<"消息发送失败,对端已关闭"<sockfd<<"】断开了连接.."<sockfd);
}

int TcpServer::StartCreateThread(){
	//接受一个连接
	int _clnt_sock = Accept();
	if(_clnt_sock <= 0){
		cout<<"接受连接失败..."<sockfd 	= _clnt_sock;			//socket描述符
	ds->ip_addr 	= inet_ntoa(clnt_addr.sin_addr);//ip地址 
	ds->id 		= socket_id;
	_descript_socket.push_back(ds);

	//开启一个线程
	std::thread _thread(&TcpServer::EchoThread , this , ds);
	_thread.detach();
	
	//线程信息id
	socket_id++;
	return 1;
}

void TcpServer::CloseServerSock(){
	if(serv_sock > 0){
		cout<<"关闭了监听socket"< 0){
		cout<<"关闭了连接socket"<
/*================================================================
*   Copyright (C) 2021 ymbLite. All rights reserved.
*   
*   文件名称:main.cpp
*   创 建 者:ymbLite
*   创建日期:2021年11月03日
*   描    述:
*
================================================================*/

#include "TcpServer.h"

int main(int argc ,char* argv[]){

	if(argc != 2){
		cout<<"Usage : "<"<

第四:结尾

        线程的这个,只是简单的开辟一个线程进行回声服务端的编写,理论上还需要其他的技术,我也正在学习,这篇只是展示怎么写,写的也不是很好,应该有很多的bug。

        还是那句话,如果错误,希望海涵,初学者,希望可以帮到各位。

        需要源码的,可以留下qq号,我可以邮箱发给你。

你可能感兴趣的:(C++,网络编程,linux,网络,c++)