第一:关于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 <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string>
#include <vector>
#include <cstring>
#include <unistd.h>
#include <mutex>
#include <thread>#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*> _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;}//创建服务器中的服务端socketserv_sock = socket(PF_INET , SOCK_STREAM , 0);if(serv_sock == -1){cout<<"服务器创建监听套接字失败,socket() error!"<<endl;return false;}    //绑定服务端的socket到相应的网络地址结构中memset(&serv_addr , 0 , sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(atoi(port.c_str()));if(bind(serv_sock , (struct sockaddr*)& serv_addr , sizeof(serv_addr)) == -1){cout<<"服务器绑定套接字失败,bind() error!"<<endl;CloseServerSock();return false;}//开始监听服务端的套接字if(listen(serv_sock , 5) == -1){cout<<"服务端监听套接字失败,listen() error!"<<endl;CloseServerSock();return false;}cout<<"服务端初始化完成,开始接受客户端的连接..."<<endl;return true;
}int TcpServer::Accept(){//判断服务端是否已经开启了socketif(serv_sock == -1){cout<<"服务器中未开启监听的socket,Accept() error!"<<endl;return 0;}clnt_addr_len = sizeof(clnt_addr);clnt_sock = accept(serv_sock , (struct sockaddr*)& clnt_addr , &clnt_addr_len);return clnt_sock;
}void TcpServer::EchoThread( descript_socket* _descript_socket ){cout<<"Echo thread_id ["<<std::this_thread::get_id()<<"] Start Run..."<<endl;cout<<"[sockfd:"<<_descript_socket->sockfd<<"\tip_addr:"<<_descript_socket->ip_addr<<"\tid:"<<_descript_socket->id<<"]"<<endl;//开始接收客户端发送的信息int msg_len;char msg[BUFF_SIZE];while(TcpBaseRead(_descript_socket->sockfd , msg , &msg_len)){msg[msg_len] = 0;cout<<"【"<<_descript_socket->sockfd<<"】:"<<msg<<endl;if(!TcpBaseWrite(_descript_socket->sockfd , msg)){cout<<"消息发送失败,对端已关闭"<<endl;break;}}cout<<"【"<<_descript_socket->sockfd<<"】断开了连接.."<<endl;cout<<"Echo thread_id ["<<std::this_thread::get_id()<<"] Stop Run..."<<endl;//关闭连接close(_descript_socket->sockfd);
}int TcpServer::StartCreateThread(){//接受一个连接int _clnt_sock = Accept();if(_clnt_sock <= 0){cout<<"接受连接失败..."<<endl;return -1;}//连接成功//首先保存服务器连接的客户端信息descript_socket* ds = new descript_socket;ds->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();//线程信息idsocket_id++;return 1;
}void TcpServer::CloseServerSock(){if(serv_sock > 0){cout<<"关闭了监听socket"<<endl;close(serv_sock);serv_sock = -1;}
}void TcpServer::CloseClientSock(){if(clnt_sock > 0){cout<<"关闭了连接socket"<<endl;close(clnt_sock);serv_sock = -1;}
}
/*================================================================
*   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 : "<<argv[0]<<" <PORT>"<<endl;return -1;}//创建服务端的socketTcpServer tcp_server;//初始化服务器bool init_res = tcp_server.InitServer(argv[1]);if(!init_res){cout<<"服务器初始化失败"<<endl;return -1;}//开始while(1){int res = tcp_server.StartCreateThread();if(res == 0){break;}}   //关闭tcp_server.CloseServerSock();return 0;
}

第四:结尾

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

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

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

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

  1. Linux下基于C/C++的Socket编程基础

    什么是Socket Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程, ...

  2. linux下的C语言开发(网络编程)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 不管在Windows平台下面还是在Linux平台下面,网络编程都是少不了的.在互联网发达的今天 ...

  3. linux下基于c++使用opencv的cpu和gpu版本提取tvl1光流

    使用opencv c++版本提取tvl1光流 前言 Gpu版本 cpu版本 配置文件及运行 前言 在计算机视觉中,光流可以用来反映视频中的信息,在行为识别,跟踪,视频分割等任务中都使用.对光流不了解的 ...

  4. 流式套接字:基于TCP协议的Socket网络编程(案例2)

    案例:在案例1的基础上实现一个服务器对应多个客户端(多线程),且获得每个客户端的IP. 线程代码: package com.yh.mySocket;import java.io.BufferedRea ...

  5. Python Socket网络编程(一)初识Socket和Socket初步使用

    目录 前言 网络编程 实质 IP地址和端口 数据传输协议 协议 Socket 概念 套接字 socket对象方法 初步使用 功能 源码 运行结果 结语 前言 本系列博客是笔者学习Python Sock ...

  6. Python Socket网络编程(二)局域网内和局域网与广域网的持续通信

    目录 前言 IP地址 简介 公有IP 私有IP 局域网之间网络通信 前提 功能描述 源码 运行结果 局域网与广域网网络通信 前提 源码 结语 前言 本系列博客是笔者学习Python Socket的过程 ...

  7. 基于Linux的socket网络编程项目——游侠手机商城

    基于Linux的socket网络编程项目--游侠手机商城 一.项目说明 二.项目使用的技术 三.客户端搭建 四.服务器端搭建 一.项目说明 本项目是一个仿真手机商城类系统,基本功能: 登录界面功能:用 ...

  8. Linux下基于TCP的简易文件传输(socket编程)

    Linux下基于TCP的简易文件传输(socket编程) OSI和TCP/IP: 关于TCP/IP协议 关于TCP协议 TCP编程的一般步骤[^2] TCP文件传输实现 功能概述 服务器编程 客户端编 ...

  9. linux下C语言socket网络编程简例

    转自博文:http://blog.csdn.net/kikilizhm/article/details/7858405 在练习写网络编程时,该例给了我帮助,在写服务器时,我把while逻辑位置想法错了 ...

最新文章

  1. Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
  2. [原创]Silverlight与PostgreSQL数据库的互操作(CURD完全解析)
  3. 构建javaweb项目
  4. wifi共享大师电脑版_Wifi分析助手PC版-Wifi分析助手电脑版下载 v7.2.2-
  5. 超长数列中n个整数排序C++代码实现
  6. hadoop2.0以后不需要借助cywin运行在Windows上
  7. tinymce vue 部分工具不显示_tinymce-vue使用问题及解决记录
  8. 绝了,66道并发多线程面试题汇总
  9. 实验四+040+薛龚
  10. 刷卡读取信息自动录入表格_人事自动化管理系统.xls
  11. 网站html页面显示404错误,网站怎样设置404错误页面
  12. 树莓派PI2编译天猫魔盘驱动,附编译好ko文件
  13. 9针串口的RS232、RS485、RS422引脚定义
  14. 桑格测序服务市场现状及未来发展趋势
  15. WDS桥接和WDS中继的区别
  16. 实用又方便电脑快捷键
  17. MySQL DATE_SUB() -- 从日期减去指定的时间间隔
  18. 高中数学必修2试题:直线平面平行的判定及其性质
  19. 忘记本地mysql密码_本地MySQL密码忘了,怎么找回?
  20. Linux系统配置网卡ip地址

热门文章

  1. matlab弹奏旋律(发声)笔记
  2. 随机数字信号处理实验报告三——Levinson和Burg递推法MATLAB实现
  3. 云直播丁云鹏:最可怕的,是你低估生活的残酷
  4. 图论——最短路径之渡河问题
  5. 【Unity3D】AR游戏制作 - Sikuto's Farm
  6. 【Android】多语言适配:语言、名称、与资源对应关系
  7. 简单易学的win10安装教程,值得收藏
  8. svg元素 标签增加、移除class名
  9. Linux C语言 pthread_cond_wait()、pthread_cond_timedwait()函数(不允许cond被唤醒时产生竞争,所以需要和互斥锁搭配)
  10. Testin云测试平台