跨平台Socket封装——CSocketImpl类
来源:互联网 发布:淘宝店无线端装修 编辑:程序博客网 时间:2024/05/22 08:08
头文件SocketImpl.h
namespace LinWin{ class CSocketImpl { private: net_socket_fd m_sock; bool m_bBlocking; public: CSocketImpl(); CSocketImpl(net_socket_fd sockfd); CSocketImpl(const CSocketImpl& iml); virtual ~CSocketImpl(); public: virtual int Create(int af = AF_INET, int type = SOCK_STREAM, int proto = 0); virtual void Close(); virtual int Bind(const CSocketAddress& address); virtual int Listen(int backlog = 64); virtual int Accept(CSocketImpl* connfd, CSocketAddress& clientAddr); virtual int Connect(const CSocketAddress& addr); virtual int SendBytes(const void* lpBuf, unsigned int lpLen, int flag = 0); virtual int RecvBytes(void* lpBuf, unsigned int lpLen, int flag = 0); virtual int SendBytesto(const void* lpBuf, unsigned int lpLen, const CSocketAddress& addr, int flag = 0); virtual int RecvBytesfrom(void* lpBuf, unsigned int lpLen, CSocketAddress& addr, int flag = 0); virtual int ShutdownReceive(); virtual int ShutdownSend(); virtual int Shutdown(); virtual int SetSendBufferSize(int size); virtual int GetSendBufferSize(int& size); virtual int SetReceiveBufferSize(int size); virtual int GetReceiveBufferSize(int& size); virtual int LocalAddress(CSocketAddress& localAddr); virtual int RemoteAddress(CSocketAddress& remoteAddr); virtual int Available(int& result); int SetOption(int level, int option, int value); int SetOption(int level, int option, unsigned value); int SetOption(int level, int option, unsigned char value); virtual int SetRawOption(int level, int option, const void* value, int length); int GetOption(int level, int option, int& value); int GetOption(int level, int option, unsigned& value); int GetOption(int level, int option, unsigned char& value); virtual int GetRawOption(int level, int option, void* value, int length); int SetLinger(bool on, int seconds); int GetLinger(bool& on, int& seconds); int SetNoDelay(bool flag); int GetNoDelay(bool& flag); int SetKeepAlive(bool flag); int GetKeepAlive(bool& flag); int SetReuseAddress(bool flag); int GetReuseAddress(bool& flag); virtual int SetBlocking(bool flag); virtual bool GetBlocking() const; net_socket_fd Sockfd() const; const net_socket_fd* Handle() const { return reinterpret_cast<const net_socket_fd*>(&m_sock); } int SocketError(); virtual int Ioctl(net_ioctl_request_t request, int& arg); virtual int Ioctl(net_ioctl_request_t request, void* arg); }}
Socket网络编程最基本的操作都封装在这里了,随后再把扩展的加进来。net_socket_fd类型的定义是为了统一平台之间的差异,它的定义已在platform.h文件中更新(在之前博客中)。
SocketImpl.cpp文件
#include "SocketImpl.h"LinWin::CSocketImpl::CSocketImpl() : m_sock(NET_INVALID_SOCKET), m_bBlocking(false){}LinWin::CSocketImpl::CSocketImpl(net_socket_fd sock) : m_sock(sock), m_bBlocking(false){}LinWin::CSocketImpl::CSocketImpl(const CSocketImpl& iml) : m_sock(iml.m_sock), m_bBlocking(iml.m_bBlocking){}LinWin::CSocketImpl::~CSocketImpl(){ Close();}int LinWin::CSocketImpl::Create(int af /* = AF_INET */, int type /* = SOCK_STREAM */, int proto /* = 0 */){ m_sock = ::socket(af, type, proto); return m_sock == NET_INVALID_SOCKET ? -1 : 0;}void LinWin::CSocketImpl::Close(){ if (m_sock != NET_INVALID_SOCKET) { closesocket(m_sock); m_sock = NET_INVALID_SOCKET; }}int LinWin::CSocketImpl::Bind(const CSocketAddress& address){ if (m_sock == NET_INVALID_SOCKET) return -2; if (::bind(m_sock, reinterpret_cast<const struct sockaddr *>(address.GetAddress()), address.AddressLength()) != 0) return -1; return 0;}int LinWin::CSocketImpl::Listen(int backlog /* = 64 */){ if (m_sock == NET_INVALID_SOCKET) return -2; if (::listen(m_sock, backlog) != 0) return -1; return 0;}int LinWin::CSocketImpl::Accept(CSocketImpl* connfd, CSocketAddress& clientAddr){ if (m_sock == NET_INVALID_SOCKET || connfd == NULL) return -2; socklen_t salen = clientAddr.AddressLength(); connfd->m_sock = ::accept(m_sock, reinterpret_cast<struct sockaddr*>(clientAddr.GetAddress()), &salen); if (connfd->m_sock == NET_INVALID_SOCKET) return -1; return 0;}int LinWin::CSocketImpl::Connect(const CSocketAddress& addr){ if (m_sock == NET_INVALID_SOCKET) return -2; if (::connect(m_sock, reinterpret_cast<const struct sockaddr *>(addr.GetAddress()), addr.AddressLength()) != 0) return -1; return 0;}int LinWin::CSocketImpl::SendBytes(const void* lpBuf, unsigned int lpLen, int flag){ return ::send(m_sock, reinterpret_cast<const char*>(lpBuf), lpLen, flag);}int LinWin::CSocketImpl::RecvBytes(void* lpBuf, unsigned int lpLen, int flag){ return ::recv(m_sock, reinterpret_cast<char*>(lpBuf), lpLen, flag);}int LinWin::CSocketImpl::SendBytesto(const void* lpBuf, unsigned int lpLen, const CSocketAddress& addr, int flag){ return ::sendto(m_sock, reinterpret_cast<const char*>(lpBuf), lpLen, flag, reinterpret_cast<const struct sockaddr*>(addr.GetAddress()), addr.AddressLength());}int LinWin::CSocketImpl::RecvBytesfrom(void* lpBuf, unsigned int lpLen, CSocketAddress& addr, int flag){ socklen_t addrLen = addr.AddressLength(); return ::recvfrom(m_sock, reinterpret_cast<char*>(lpBuf), lpLen, flag, reinterpret_cast<sockaddr*>(addr.GetAddress()), &addrLen);}int LinWin::CSocketImpl::ShutdownReceive(){ return (::shutdown(m_sock, SD_RECEIVE) != 0) ? -1 : 0;}int LinWin::CSocketImpl::ShutdownSend(){ return (::shutdown(m_sock, SD_SEND) != 0) ? -1 : 0;}int LinWin::CSocketImpl::Shutdown(){ return (::shutdown(m_sock, SD_BOTH) != 0) ? -1 : 0;}int LinWin::CSocketImpl::SetSendBufferSize(int size){ return SetOption(SOL_SOCKET, SO_SNDBUF, size);}int LinWin::CSocketImpl::GetSendBufferSize(int& size){ return GetOption(SOL_SOCKET, SO_SNDBUF, size);}int LinWin::CSocketImpl::SetReceiveBufferSize(int size){ return SetOption(SOL_SOCKET, SO_RCVBUF, size);}int LinWin::CSocketImpl::GetReceiveBufferSize(int& size){ return GetOption(SOL_SOCKET, SO_RCVBUF, size);}int LinWin::CSocketImpl::LocalAddress(CSocketAddress& localAddr){ socklen_t saLen = sizeof(struct sockaddr_in); int rc = ::getsockname(m_sock, reinterpret_cast<struct sockaddr*>(localAddr.GetAddress()), &saLen); return rc != 0 ? -1 : 0;}int LinWin::CSocketImpl::RemoteAddress(CSocketAddress& remoteAddr){ socklen_t saLen = sizeof(struct sockaddr_in); int rc = ::getpeername(m_sock, reinterpret_cast<struct sockaddr*>(remoteAddr.GetAddress()), &saLen); return rc != 0 ? -1 : 0;}int LinWin::CSocketImpl::Available(int& result){ return Ioctl(FIONREAD, result);}int LinWin::CSocketImpl::SetOption(int level, int option, int value){ return SetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::SetOption(int level, int option, unsigned value){ return SetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::SetOption(int level, int option, unsigned char value){ return SetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::SetRawOption(int level, int option, const void* value, int length){ int rc = ::setsockopt(m_sock, level, option, reinterpret_cast<const char*>(value), (socklen_t)length); return rc == -1 ? -1 : 0;}int LinWin::CSocketImpl::GetOption(int level, int option, int& value){ return GetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::GetOption(int level, int option, unsigned& value){ return GetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::GetOption(int level, int option, unsigned char& value){ return GetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::GetRawOption(int level, int option, void* value, int length){ int rc = ::getsockopt(m_sock, level, option, reinterpret_cast<char*>(value), reinterpret_cast<socklen_t*>(&length)); return rc == -1 ? -1 : 0;}int LinWin::CSocketImpl::SetLinger(bool on, int seconds){ struct linger l; l.l_onoff = on ? 1 : 0; l.l_linger = seconds; return SetRawOption(SOL_SOCKET, SO_LINGER, &l, sizeof(l));}int LinWin::CSocketImpl::GetLinger(bool& on, int& seconds){ struct linger l; int len = sizeof(l); int ret = GetRawOption(SOL_SOCKET, SO_LINGER, &l, len); if (ret == 0) { on = (l.l_onoff != 0); seconds = l.l_linger; } return ret;}int LinWin::CSocketImpl::SetNoDelay(bool flag){ int value = flag ? 1 : 0; return SetOption(IPPROTO_TCP, TCP_NODELAY, value);}int LinWin::CSocketImpl::GetNoDelay(bool& flag){ int value = 0; int ret = GetOption(IPPROTO_TCP, TCP_NODELAY, value); if (ret == 0) flag = (value != 0); return ret;}int LinWin::CSocketImpl::SetKeepAlive(bool flag){ int value = flag ? 1 : 0; return SetOption(SOL_SOCKET, SO_KEEPALIVE, value);}int LinWin::CSocketImpl::GetKeepAlive(bool& flag){ int value(0); int ret = GetOption(SOL_SOCKET, SO_KEEPALIVE, value); if (ret == 0) flag = (value != 0); return ret;}int LinWin::CSocketImpl::SetReuseAddress(bool flag){ int value = flag ? 1 : 0; return SetOption(SOL_SOCKET, SO_REUSEADDR, value);}int LinWin::CSocketImpl::GetReuseAddress(bool& flag){ int value(0); int ret = GetOption(SOL_SOCKET, SO_REUSEADDR, value); if (ret == 0) flag = (value != 0); return ret;}int LinWin::CSocketImpl::SetBlocking(bool flag){#ifdef WINDOWS_FAMILY unsigned long nonblocking = flag ? 1 : 0; if (ioctlsocket(m_sock, FIONBIO, (unsigned long*)&nonblocking) == SOCKET_ERROR) return -1;#else int opts; opts = fcntl(m_sock, F_GETFL); if (opts < 0) return -1; if (flag) opts = opts | O_NONBLOCK; else opts = opts & (~O_NONBLOCK); if (fcntl(m_sock, F_SETFL, opts) < 0) return -1;#endif m_bBlocking = flag; return 0;}bool LinWin::CSocketImpl::GetBlocking() const{ return m_bBlocking;}net_socket_fd LinWin::CSocketImpl::Sockfd() const{ return m_sock;}int LinWin::CSocketImpl::Ioctl(net_ioctl_request_t request, int& arg){ int rc;#ifdef WINDOWS_FAMILY rc = ioctlsocket(m_sock, request, reinterpret_cast<u_long*>(&arg));#else rc = ::ioctl(m_sock, request, &arg);#endif return (rc != 0) ? -1 : 0;}int LinWin::CSocketImpl::Ioctl(net_ioctl_request_t request, void* arg){ int rc;#ifdef WINDOWS_FAMILY rc = ioctlsocket(m_sock, request, reinterpret_cast<u_long*>(arg));#else rc = ::ioctl(m_sock, request, arg);#endif return (rc != 0) ? -1 : 0;}int LinWin::CSocketImpl::SocketError(){#ifdef WINDOWS_FAMILY return GetLastError();#else return errno;#endif}
由于CSocketAddress类中添加了一个非const版本的GetAddress成员函数,所以去掉此类中所有const_cast的转换。
0 0
- 跨平台Socket封装——CSocketImpl类
- 跨平台Socket封装——CTcpClient类
- 跨平台Socket封装——跨平台头文件
- 跨平台Socket封装
- 跨平台Socket封装
- 跨平台Socket封装
- c++ 跨平台封装socket
- 跨平台Socket封装 odsocket
- 跨平台Socket封装——对IPv4地址的封装
- 跨平台Socket封装——一个服务端代码和客户端代码示例
- 跨平台(Windows+Linux)的Socket通讯程序(一)—底层封装
- 跨平台的游戏客户端Socket封装
- 跨平台的游戏客户端Socket封装
- 跨平台的游戏客户端Socket封装
- 跨平台的游戏客户端Socket封装
- 跨平台的游戏客户端Socket封装
- 跨平台的游戏客户端Socket封装
- sock_ev——linux平台socket事件框架(socket API的封装)
- 前端XSS攻击的三种方式
- Struts2.5 提示:ERROR ParametersInterceptor Developer Notification 原因解释
- Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组
- 如何依照自己的意愿隐藏和显示页面上的元素
- IARPA的量子计算机研发计划
- 跨平台Socket封装——CSocketImpl类
- Python写一个小小的项目监控
- 穷人富人
- T3 - 用友通标准版本 客户端安装 遇到的坑
- 在线画图工具
- hive独立模式环境搭建
- jquery 滚动条 scroll 和 animate出现的问题总结
- MFC CBitmapButton类的应用
- 常用GIT代码托管平台