1. 封装Socket
常用的标准函数接口:
- socket() 创建新的套接字并分配系统资源
- bind() 一般用于服务端,将套接字与套接字地址(IP及本地端口)绑定
- listen() 一般用于服务端,将绑定的TCP置于监听状态
- connect() 一般用于客户端,分配一个本地的空闲端口,并与服务端建立连接
- accept() 一般用于服务端,接受一个新的连接请求,并创建一个与该链接绑定的套接字
- send(), recv() 或 write(), read() 或 sendto(), recvfrom() 用于发送和接收数据
- close() 关闭一个打开的套接字并释放资源
- select() 用于等待一个或多个指定套接字的下一个读写事件
- poll() 用于测试一个或多个套接字的读写状态
- gethostbyname(),gethostbyaddr() 在IPv4协议中解析域名和地址
- getsockopt() 获取指定套接字的参数
- setsockopt() 设置指定套接字的参数
相关接口的知识延伸:socket接口api的深度探究
封装部分接口:
封装
core.hpp的宏定义:
/* 打印需要的宏定义*/
#define OSS_MAX_PATHSIZE PATH_MAX //路径最大长度
#define OSS_FILE_SEP_STR "/" //路径分隔符
#define OSS_FILE_SEP_CHAR *((const char*)OSS_FILE_SET_STR)[0] //分割字>符
#define OSS_NEWLINE "\n" //换行符 linux->\n, windows->\r\n
/*错误代码的宏定义*/
#define EDB_OK 0 //正常
#define EDB_IO -1 //IO错误
#define EDB_INVALIDARG -2 //非法参数
#define EDB_PERM -3 //权限错误
#define EDB_OOM -4 //内存不足
#define EDB_SYS -5 //系统错误
#define EDB_PMD_HELP_ONLY -6 //
#define EDB_PMD_FORCE_SYSTEM_EDU -7 //
#define EDB_TIMEOUT -8 //超时错误
#define EDB_QUIESCED -9 //
#define EDB_EDU_INVAL_STATUS -10 //
#define EDB_NETWORK -11 //网络错误
#define EDB_NETWORK_CLOSE -12 //网络关闭错误
#define EDB_APP_FORCED -13 //
#define EDB_IXM_ID_EXIST -14 //
#define EDB_HEADER_INVALID -15 //
#define EDB_IXM_ID_NOT_EXIST -16 //
#define EDB_NO_ID -17 //
ossSocket.hpp的头文件:
#include "core.hpp"
#define SOCKET_GETLASTERROR errno
//默认超时10ms
#define OSS_SOCKET_DFT_TIMEOUT 10000
//最大的hostname和servicename的长度
#define OSS_MAX_HOSTNAME NI_MAXHOST
#define OSS_MAX_SERVICENAME NI_MAXSERV
class _ossSocket{
private:
int _fd;
socklen_t _addressLen;
sokclen_t _peerAddressLen;
struct sockaddr_in _sockAddress;
struct sockaddr_in _peerAddress;
bool _init;
int _timout;
protected:
unsigned int _getPort( sockaddr_in *addr);
int _getAddress( sockaddr_in *addr, char *pAddress, unsigned int length);
public:
int setSocketLi(int lOnOff, int linger);
void setAddress( const char *pHostName, unsigned int port);
_ossSocket();
//创建监听socket,输入需要监听的port
_ossSocket(unsigned int port, int timeout = 0);
//创建请求连接的客户端socket,输入远程服务的ip和port
_ossSocket(const char *pHostName, unsigned int port, int timeout = 0);
//用于accept,生成新接入的客户socket
_ossSocket(int *sock, int timeout);
~_ossSocket(){ close(); }
int initSocket();
int bind_listen();
int send(const char *pMsg, int len,
int timeout = OSS_SOCKET_DEF_TIMEOUT,
int flags = 0);
//如果timeout=0,代表永不超时,即recv会等到接收的数据达到len长度,才会返回
int recv(char *pMsg, int len,
int timeout = OSS_SOCKET_DEF_TIMEOUT,
int flags = 0);
//只要收到数据,就会立刻返回
int recvNF(char *pMsg, int len,
int timeout = OSS_SOCKET_DEF_TIMEOUT);
int connect();
void close();
int accept( int *sock, struct sockaddr * addr, socklen_t * addrlen,
int timeout = OSS_SOCKET_DEF_TIMEOUT);
//关闭发送的打包功能,让小包也能即刻发送
int disableNagle();
unsigned int getPeerPort();
//获取对方的IP
int getPeerAddress(char *pAddress, unsigned int length);
unsigned int getLocalPort();
//获取本地的IP
int getLocalAddress(char *pAddress, unsigned int length);
int setTimeout( int seconds);
//获取本机域名
static int getHostName(char *pName, int nameLen);
//获取服务程序占用的端口号
static int getPort(const char *pServiceName, unsigned short &port);
}
typedef class _ossSocket ossSocket;