linux socket_stream,Linux socket类,支持AF_INET/AF_UNIX STREAM/DGRAM
学习python时发现,socket和SocketServer的方便快捷,于是研究了一下socket和SocketServer.py写了一下C++版本的。
陆续分享一下。
1. socket类socket_t
socket++.h
/* class socket_t
* Description
* Simulation to python socket class
* Author
* wfb
* Version
* 0.1.0
* 2010/7/25
*/
#ifndef __SOCKET_PLUS_H__
#define __SOCKET_PLUS_H__
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace ss
{
// it's NOT defined in (JUST A MAGIC, don't know y)
const size_t UNIX_PATH_MAX = 108;
/* address_t
* host[string] for ipaddress in ip4, unix-domain in AF_UNIX (ip6 NOT SUPPOSED RIGHT NOW, it's easy to)
* port[ushort] invalid for AF_UNIX
*/
struct address_t
{
std::string host;
unsigned short port;
address_t():host(""), port(0){}
address_t(const std::string& h, unsigned short p) : host(h), port(p){}
address_t(const address_t& add) : host(add.host), port(add.port){}
};
/* class socket_t
* int create();
* int create_from(int fileno);
* int accept(socket_t& socket, address_t& address);
* int bind(address_t& address);
* int listen(int backlog=5);
* int connect(const address_t& address);
* int close();
* int setsockopt(int level, int optname, int optval);
* int getsockopt(int level, int optname, int& optval);
* int reuse_address(int on=1
* int linger(int timeout=5);
* int send();
* int recv();
* int sendto();
* int recvfrom();
* int setblocking(int on=1);
* int fileno()const{return m_fileno;}
* int last_errno()const;
* int makefile();
*/
class socket_t
{
public:
socket_t():m_fileno(-1), m_ref(NULL){}
socket_t(int family, int type, int proto)
: m_fileno(::socket(family, type, proto)), m_family(family), m_type(type), m_proto(proto), m_ref(new int(1))
{}
socket_t(int fileno, int* pref, int family, int type, int proto)
: m_fileno(fileno), m_family(family), m_type(type), m_proto(proto), m_ref(pref ? pref : new int(1))
{}
socket_t(socket_t& sock)
: m_fileno(sock.m_fileno), m_family(sock.m_family), m_type(sock.m_type), m_proto(sock.m_proto), m_ref(sock.m_ref)
{
ref();
}
socket_t& operator=(socket_t& sock);
~socket_t(){close();}
int create();
int create_from(int fileno);
int accept(socket_t& socket, address_t& address);
int bind(address_t& address);
int listen(int backlog=5);
int connect(const address_t& address);
int close();
int setsockopt(int level, int optname, int optval);
int getsockopt(int level, int optname, int& optval);
int reuse_address(int on=1){return setsockopt(SOL_SOCKET, SO_REUSEADDR, on);}
int linger(int timeout=5);
/* TODO
int send();
int recv();
int sendto();
int recvfrom();
*/
int setblocking(int on=1);
int fileno()const{return m_fileno;}
int last_errno()const{return m_errno;}
int makefile(){return 0;}
private:
int ref(){if(NULL==m_ref)return 0;return ++*m_ref;}
int dref(){if(NULL==m_ref)return 0;return --*m_ref;}
private:
int m_fileno;
int m_family;
int m_type;
int m_proto;
int m_errno;
int* m_ref;
};
} // namespace ss
#endif //__SOCKET_PLUS_H__
socket++.cpp
#include "socket++.h"
namespace ss
{
socket_t& socket_t::operator=(socket_t& sock)
{
if (this==&sock) return *this;
this->close();
m_family = sock.m_family;
m_type = sock.m_type;
m_proto = sock.m_proto;
m_fileno = sock.m_fileno;
m_ref = sock.m_ref;
ref();
return *this;
}
int socket_t::create_from(int fileno)
{
if (m_ref) return m_fileno;
m_fileno = fileno;
m_ref = new int(1);
return m_fileno;
}
int socket_t::close()
{
int ret = 0;
if (m_ref && dref()<=0)
{
delete m_ref;
m_ref = NULL;
ret = ::close(m_fileno);
m_fileno = -1;
}
return ret;
}
int socket_t::bind(address_t& address)
{
sockaddr_in addr_in;
sockaddr_un addr_un;
sockaddr* paddr = NULL;
socklen_t addrlen = 0;
if (AF_INET==m_family)
{
bzero(&addr_in, sizeof(addr_in));
addr_in.sin_port = ::htons(address.port);
addr_in.sin_family = m_family;
if ((::inet_pton(m_family, address.host.c_str(), &addr_in.sin_addr)<=0))
{
m_errno = errno;
return -1;
}
paddr = (sockaddr*)&addr_in;
addrlen = sizeof(addr_in);
}
else if (AF_UNIX==m_family)
{
bzero(&addr_un, sizeof(addr_un));
addr_un.sun_family = AF_UNIX;
strncpy(addr_un.sun_path, address.host.c_str(), std::min(UNIX_PATH_MAX-1, address.host.size()));
address.host = addr_un.sun_path;
paddr = (sockaddr*)&addr_un;
addrlen = sizeof(addr_un);
}
else // AF_INET6 NOT supported
{
return -1;
}
if (::bind(m_fileno, paddr, addrlen))
{
m_errno = errno;
return -1;
}
return 0;
}
int socket_t::listen(int backlog/*=5*/)
{
int ret = ::listen(m_fileno, backlog);
if (ret)
{
m_errno = errno;
}
return ret;
}
int socket_t::accept(socket_t& socket, address_t& address)
{
sockaddr_in addr_in;
sockaddr_un addr_un;
sockaddr* paddr = NULL;
socklen_t addrlen = 0;
if (AF_INET==m_family)
{
bzero(&addr_in, sizeof(addr_in));
paddr = (sockaddr*)&addr_in;
addrlen = sizeof(addr_in);
}
else if (AF_UNIX==m_family)
{
bzero(&addr_un, sizeof(addr_un));
paddr = (sockaddr*)&addr_un;
addrlen = sizeof(addr_un);
}
int fd = ::accept(m_fileno, paddr, &addrlen);
if (fd>0)
{
if (AF_INET==m_family)
{
address.host = std::string(::inet_ntoa(addr_in.sin_addr));
address.port = ::ntohs(addr_in.sin_port);
}
else if (AF_UNIX==m_family)
{
address.host = addr_un.sun_path;
}
else
{
return -1;
}
socket_t client_sock(fd, NULL, m_family, m_type, m_proto);
socket = client_sock;
}
return fd;
}
int socket_t::connect(const address_t& address)
{
sockaddr_in addr_in;
sockaddr_un addr_un;
sockaddr* paddr = NULL;
socklen_t addrlen = 0;
if (m_family==AF_INET||m_family==AF_INET6)
{
bzero(&addr_in, sizeof(addr_in));
addr_in.sin_port = ::htons(address.port);
addr_in.sin_family = m_family;
if ((::inet_pton(m_family, address.host.c_str(), &addr_in.sin_addr)<=0))
{
m_errno = errno;
return -1;
}
paddr = (sockaddr*)&addr_in;
addrlen = sizeof(addr_in);
}
else if (m_family==AF_UNIX)
{
bzero(&addr_un, sizeof(addr_un));
addr_un.sun_family = AF_UNIX;
strncpy(addr_un.sun_path, address.host.c_str(), std::min(UNIX_PATH_MAX-1, address.host.size()));
paddr = (sockaddr*)&addr_un;
addrlen = sizeof(addr_un);
}
else // AF_INET6 NOT supported
{
return -1;
}
if (::connect(m_fileno, paddr, addrlen))
{
m_errno = errno;
return -1;
}
return 0;
}
int socket_t::setsockopt(int level, int optname, int optval)
{
int ret = ::setsockopt(m_fileno, level, optname, &optval, sizeof(optval));
if (ret)
{
m_errno = errno;
}
return ret;
}
int socket_t::getsockopt(int level, int optname, int& optval)
{
socklen_t optlen = sizeof(optval);
int ret = ::getsockopt(m_fileno, level, optname, &optval, &optlen);
if (ret)
{
m_errno = errno;
}
return ret;
}
int socket_t::setblocking(int on/*=1*/)
{
int ret = 0;
int val = 0;
if ((val = ::fcntl(m_fileno, F_GETFL)) == -1 && errno)
{
m_errno = errno;
return -1;
}
switch (on)
{
case 0:
if (val & O_NONBLOCK)
{
ret = ::fcntl(m_fileno, F_SETFL, 0);
}
break;
default:
if (!(val & O_NONBLOCK))
{
ret = ::fcntl(m_fileno, F_SETFL, 1);
}
break;
}
if (ret)
{
m_errno = errno;
}
return ret;
}
int socket_t::linger(int timeout/*=5*/)
{
struct linger lg;
lg.l_onoff=timeout>0?1:0;
lg.l_linger=timeout;
int ret = ::setsockopt(m_fileno, SOL_SOCKET, SO_LINGER, &lg, sizeof(lg));
if (ret)
{
m_errno = errno;
}
return ret;
}
} //namespace ss
linux socket_stream,Linux socket类,支持AF_INET/AF_UNIX STREAM/DGRAM相关推荐
- linux C语言 socket编程教程(附两个例子)(socket教程)
文章目录 1.网络中进程之间如何通信? 2.什么是Socket? 3.socket的基本操作 3.1.socket()函数 3.2.bind()函数 网络字节序与主机字节序 3.3.listen(). ...
- linux中高并发socket最大连接数的优化详解
这篇文章主要给大家介绍了关于linux中高并发socket最大连接数优化的相关资料,文中介绍的很详细,相信对大家具有一定的参考价值,需要的朋友们下面来一起学习学习吧. 首先我们可以通过ulimit – ...
- Linux 网络编程socket错误分析
socket错误码: EINTR: 4 阻塞的操作被取消阻塞的调用打断.如设置了发送接收超时,就会遇到这种错误. 只能针对阻塞模式的socket.读,写阻塞的socket时,-1返回,错误号为INTR ...
- Linux 详解socket实现与网络编程接口
如何理解套接字 根据底层网络机制的差异,计算机网络世界中定义了不同协议族的套接字(socket),比如 DARPA Internet 地址(Internet 套接字).本地节点的路径名(Unix 套接 ...
- linux下的socket通信
linux下的socket通信 在linux下,无论多么复杂的服务器或客户端程序,无论什么编程语言实现的,其底层都离不开linux内核提供的系统调用(也就十多个函数),其网络通信的基本流程一定如下所述 ...
- Linux 网络编程——socket 网络编程
文章目录 一.网络基础 TCP/UDP对比 TCP/IP协议族体系 socket IP地址 IP地址转化API inet_addr() inet_aton() inet_ntoa() inet_pto ...
- Linux中的socket编程
目录 0.前言 1.Linux中socket编程接口详解 1.1.socket函数 1.2.bind函数 为什么addr参数要使用sockaddr_in 结构体,然后再强制转换为 sockaddr 类 ...
- Kali Linux NetHunter教程Kali NetHunter支持的设备和ROMs
Kali Linux NetHunter教程Kali NetHunter支持的设备和ROMs NetHunter是一个基于Kali Linux为Nexus设备构建的Android渗透测试平台,其中包括 ...
- 在Unix/Linux上令(java)JVM支持中文输出
在Unix/Linux上令(java)JVM支持中文输出 一.在Unix/Linux上令JVM支持中文输出 如 果用户使用的是UNIX的远程服务器,就会遇到中文字体在图像中输出的问题,特别是由于许多管 ...
最新文章
- VBA【遍历每个工作表并将工作表表名赋予B2单元格】
- c语言词法分析程序,词法分析器(c语言实现)
- Lambda表达式的注意事项【理解】
- 误落迷宫2(BFS)
- java创建一副牌_用java怎么创建一副扑克牌
- 仿途牛旅游APP项目开发
- 分离圆环图显示百分比_excel这个百分比图,你不一定会制作
- Qt + 运动控制 (固高运动控制卡)【3】运动控制卡几种常用的回零方式
- oracle中文转全拼音,(转)oracle下,把中文转为拼音函数编写
- vld(Visual Leak Detector)下载地址和源码地址
- 如何从零基础入门并精通PS?PS如何快速入门?
- 云帆文档易用性功能设计之文档查阅
- yii2授权之ACF
- 智能算法系列之粒子群优化算法
- Greedy——HDOJ 1789
- c# 两个日期之间的比较与两个日期相差天数计算
- 工欲善其事,必先利其器--vim-tips
- 嵌入式Linux驱动笔记(二十九)------内存管理之伙伴算法(Buddy)分析
- TCP/IP协议的send和recieve
- stm32定时器的四个通道是什么意思
热门文章
- 电子地图应用能否保障清明扫墓客流的有序安全?
- xp系统如何查看计算机用户,WinXP系统怎么查看电脑使用记录? XP系统电脑使用记录的查看方法...
- 分享四个特别好用的app,真的太好用了
- 华为Matebook X 成功安装黑苹果
- XFS: possible memory allocation deadlock in kmem_alloc
- 【Linux】rm -rf 血的教训
- php解析 虾米音乐地址解析,用PHP获取虾米音乐网的下载链接
- 正则计算器版中版之最后一版!
- vCenter Server 7.0 Update 3a Build 8778458
- Oracle使用imp和impdp导入数据