Linux socket编程(一) 对套接字操作的封装
转载:http://www.cnblogs.com/-Lei/archive/2012/09/04/2670942.html
以前写的,现在回顾一下:
下面是对socket操作的封装,因为在Linux下写中文到了windows里面会乱码,所以注释用英文来写,有空再查下解决方法吧
socket.h
#ifndef SOCKET_H #define SOCKET_H#include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string>const int MAXCONNECTION=5; const int MAXRECEIVE = 500;class Socket {public:Socket();//virtual destructiorvirtual ~Socket();// Server initializationbool Create(); //create a socketbool Bind(const int port);bool Listen() const;bool Accept(Socket& clientSocket) const;// Client initializationbool Connect(const std::string& host,const int port);// Data Transmissionbool Send(Socket& socket,const std::string& message) const;int Receive(Socket& socket,std::string& message) const;void SetNonBlocking(const bool flag);bool IsValid() const;private://use m_sockfd to record the result of function socketint m_sockfd;struct sockaddr_in m_address; };#endif
这里解释下为什么析构函数是虚的,如果要用到多态的话,也就是用一个指向基类的指针来处理对不同到对象
如果类的成员函数不是虚函数,只是个普通的函数,那么会出现一种静态绑定到情况,如
Base* pBase = new Derive; //这里Base的析构函数不是虚函数
delete pBase; //这里只会调用Base::~Base(),所以派生类部分的资源将得不到释放
如果析构函数是虚函数的话,那么将调用Derive::~Derive(),由于我们提供了派生类的析构函数,编译器会扩展这个析构函数,
在里面调用基类的析构函数,这样派生类和基类的资源都将得到释放
socket.cpp
#include "Socket.h" #include <stdlib.h> #include <memory.h> #include <iostream> #include <fcntl.h>Socket::Socket() :m_sockfd(-1) { }Socket::~Socket() {if(IsValid())::close(m_sockfd); }//server function bool Socket::Create() {m_sockfd=socket(AF_INET,SOCK_STREAM,0);if(!IsValid())return false;return true; }bool Socket::Bind(const int port) {if(!IsValid())return false;m_address.sin_family=AF_INET;m_address.sin_addr.s_addr = htonl(INADDR_ANY);m_address.sin_port=htons(port);int bindReturn=bind(m_sockfd,(struct sockaddr*)&m_address,sizeof(m_address));if(bindReturn==-1)return false;return true; }bool Socket::Listen()const {if(!IsValid())return false;int listenReturn=listen(m_sockfd,MAXCONNECTION);if(listenReturn ==-1)return false;return true; }bool Socket::Accept(Socket& clientSocket) const {int clientaddrLength=sizeof(clientSocket.m_address);clientSocket.m_sockfd=::accept(m_sockfd,(struct sockaddr*)&clientSocket.m_address,(socklen_t *)&clientaddrLength);if(clientSocket.m_sockfd==-1)return false;return true; } //end server functionsbool Socket::Connect(const std::string& host,const int port) {if(!IsValid())return false;m_address.sin_family=AF_INET;m_address.sin_port=htons(port);m_address.sin_addr.s_addr=inet_addr(host.c_str());int connectReturn=::connect(m_sockfd,(struct sockaddr*)&m_address,sizeof(m_address));if(connectReturn==-1)return false;return true;}// Data Transmission bool Socket::Send(Socket& socket,const std::string& message) const {int result=::send(socket.m_sockfd,message.c_str(),message.length(),MSG_NOSIGNAL);if(result==-1)return false;return true; }int Socket::Receive(Socket& socket,std::string& message) const {char buffer[MAXRECEIVE+1];message.clear();memset(buffer,0,MAXRECEIVE+1);int numberRead=::recv(socket.m_sockfd,buffer,MAXRECEIVE,0);if(numberRead==-1){std::cout<<"error in Socket::Receive\n";return 0;}else if(numberRead==0)return 0;else{message=buffer;return numberRead;}}void Socket::SetNonBlocking(const bool flag) {if(IsValid()) { int opts; opts = fcntl ( m_sockfd, F_GETFL ); if ( opts < 0 ) { return; } if ( flag ) opts = ( opts | O_NONBLOCK ); else opts = ( opts & ~O_NONBLOCK ); fcntl ( m_sockfd, F_SETFL,opts ); }}bool Socket::IsValid() const {//if call function socket fail,it returns -1return m_sockfd!=-1; }
接下来是异常处理到类
#ifndef SocketException_H #define SocketException_H#include <string>class SocketException {public:SocketException ( std::string description ) : m_description( description ) {};~SocketException (){};std::string Description() { return m_description; }private:std::string m_description; };#endif
Linux socket编程(一) 对套接字操作的封装相关推荐
- Linux socket编程,对套接字进行封装
转自:http://www.cnblogs.com/-Lei/archive/2012/09/04/2670942.html 下面是对socket操作的封装,因为在Linux下写中文到了windows ...
- Linux网络编程:原始套接字的魔力【续】
如何从链路层直接发送数据帧 本来以为这部分都弄完了,结果有朋友反映说看了半天还是没看到如何从链路层直接发送数据.因为上一篇里面提到的是从链路层"收发"数据,结果只&q ...
- 【Linux网络编程】UDP 套接字编程
[Linux网络编程]UDP 套接字编程 [1]用户数据报协议(UDP) UDP是一个简单的传输层协议,不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,也不保证每个数 ...
- Linux环境SOCKET编程1:套接字
一.socket运行过程 服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接.在这时如果有个客户端初始化一个Socket,然 ...
- [Linux网络编程学习笔记]套接字地址结构
好久没有看那Linux网络编程这本书了,今天看到了重点部分-TCP套接字.下面先来看看套接字的地址结构 Linux系统的套接字可以支持多种协议,每种不同的协议都是用不同的地址结构.在头文件<li ...
- 【Linux网络编程】原始套接字实例:MAC 头部报文分析
通过<Linux网络编程--原始套接字编程>得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢? MAC 头部(有线 ...
- 【Linux网络编程】原始套接字编程
原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...
- Linux网络编程——Unix本地套接字
概述 今天给大家讲解网络编程中的一个内容--Unix 本地套接字. 发现很多人不知道或者不太了解 Unix 本地套接字这个概念,这也难怪,socket API 原本就是为多台主机之间网络通信设计的,并 ...
- 【Linux网络编程】原始套接字实例:MAC 地址扫描器
如果 A (192.168.1.1 )向 B (192.168.1.2 )发送一个数据包,那么需要的条件有 ip.port.使用的协议(TCP/UDP)之外还需要 MAC 地址,因为在以太网数据包中 ...
最新文章
- keras/tensorflow 模型保存后重新加载准确率为0 model.save and load giving different result
- latex 表格单元格上下左右居中_Excel文字对齐技巧:学会这6种方式,快速整理规范表格...
- 数据可视化必修课 - 图表篇
- LeetBook《程序员的算法趣题》Q18---水果酥饼日
- 赚钱的过程,也是合作的过程
- python476集免费教材_476. 数字的补数 | python|python爬虫|python入门|python教程
- Android SoundPool封装
- java单例模式调用_java单例模式使用及注意事项
- matlab中的脚本文件和函数文件
- 2020switch电信最快的dns_求教电信宽带switch用哪个dns快
- html页面颜色排列,HTML前端页面颜色的四种方法,色号表
- 甘特图是什么意思?甘特图制作步骤教程
- 用CSS3实现无限循环的无缝滚动
- ue编辑器c语言语法高亮文件,自己动手做 UEStudio/UltraEdit 的语法高亮文件 (*.uew)...
- 大学计算机基础教程excel实验报告,大学计算机基础教程excel实验报告.doc
- 跨境电商东南亚平台Shopee、Lazada到底怎么样?如何高效补单?
- 计算机打字题数字知识,电脑打字出现的是数字怎么办
- 我的世界服务器物品栏mod,[娱乐|机械]Item Lore Stats —— 自定义物品[附带强化][1.7-1.10]...
- 某知名支付系统的架构演进权威分析
- 打开虚拟机之后,客户机隔离选项变灰色不可用,如何解决
热门文章
- 平庸技术流,用 WebApi +AngularJS 实现网络爬虫
- cocos2d-x游戏开发系列教程-中国象棋02-main函数和欢迎页面
- 来几个FUNNY PICS,让大家笑一笑!
- lt form gt 在html,HTML lt;formgt; 标签的 accept
- python软件是哪个国家的品牌_有哪些好用的软件被国人误认为是外国研发的?
- react usecontext_Vue3原理实战运用,我用40行代码把他装进了React做状态管理
- dell增强保护套装还原失效_汕头长安欧尚汽车音响改装升级,还原真实音色
- win10无法开启夜间模式
- python列表总结
- 160 - 17 bjanes.3