📄 yssocket.h
字号:
#ifndef YsSocket_H_#define YsSocket_H_/** * * 文 件 名 : YsSocket.h * 创建日期 : 2006-09-10 * 作 者 : 邵凯田(skt001@163.com) * 修改日期 : $Date: 2006-10-27$ * 当前版本 : $Revision: $ * 功能描述 : SOCKET封装类 * 修改记录 : * $Log: $ **/ //#define _YSDEBUG#ifdef WIN32 //#define _INC_WINDOWS //#include <winsock2.h> #pragma pack(4) #define WIN32_LEAN_AND_MEAN //#include <winsock2.h> #include <stdio.h> #include <stdlib.h> #include <winsock2.h> //#include <afxsock.h>// MFC socket extensions #define socklen_t int #pragma comment(lib,"ws2_32.lib")#else #include <sys/socket.h> #include <arpa/inet.h> #include <sys/select.h> #include <unistd.h>#endif#include <iostream>#ifndef NULL #define NULL 0#endif#ifndef SOCKET #define SOCKET int#endif#ifndef INVALID_SOCKET#define INVALID_SOCKET -1#endif#ifndef SOCKET_ERROR#define SOCKET_ERROR -1#endif#ifndef TCP_NODELAY#define TCP_NODELAY 0x0001#endif#ifndef BYTE#define BYTE unsigned char#endif//typedef unsigned char BYTE;#include <string>using namespace std;class YsSocket{ public: YsSocket() { m_hSocket=0; m_bTcp = true; } ~YsSocket() { Close(); } SOCKET m_hSocket; private: int m_iAF; bool m_bTcp; int m_iSocketType; int m_iRecvTimeout,m_iSendTimeout; public: inline void SetSocketHandle(SOCKET sock) { m_hSocket = sock; } inline int GetSocketHandle() { return (int)m_hSocket; } inline bool IsConnected() { if(m_hSocket > 0) return true; else return false; } int Close() { #ifdef _YSDEBUG printf("into YsSocket's Close()\n"); #endif int ret=0; if(m_hSocket != 0) { ret=shutdown(m_hSocket, 2); #ifdef WIN32 closesocket(m_hSocket); #else close(m_hSocket); #endif m_hSocket = 0; } return ret; } /** * 创建SOCKET实例 */ bool Create(int af=AF_INET, int type=SOCK_STREAM, int protocol=IPPROTO_TCP) { #ifdef _YSDEBUG printf("into YsSocket's Create()\n"); #endif Close(); if(type != SOCK_STREAM) m_bTcp = false; #ifdef _WIN32 WSADATA WSAData; WSAStartup( MAKEWORD( 1, 1 ), &WSAData ); #endif m_iAF = af; m_iSocketType = type; m_hSocket = ::socket(af,type,protocol); if(m_hSocket == INVALID_SOCKET) { #ifdef _YSDEBUG printf("error in YsSocket's Create() when socket\n"); #endif return false; } if(type != SOCK_STREAM) return true; int bNodelay = 1; int err = setsockopt(m_hSocket,IPPROTO_TCP,TCP_NODELAY,(char *)&bNodelay,sizeof(bNodelay));//不采用延时算法 if ( err == SOCKET_ERROR ) { #ifdef _YSDEBUG printf("error in YsSocket's Create() when setsockopt\n"); #endif Close(); return false; } return true; } string GetPeerName() { sockaddr_in host; socklen_t iRet=sizeof(host); getpeername(m_hSocket,(sockaddr *)&host,&iRet); return inet_ntoa(host.sin_addr); } int GetPeerPort() { sockaddr_in host; socklen_t iRet=sizeof(host); getpeername(m_hSocket,(sockaddr *)&host,&iRet); return host.sin_port; } /** * 连接服务端 */ bool Connect(const char * serverIp, int port) { #ifdef _YSDEBUG printf("into YsSocket's Connect(%s,%d)\n",serverIp,port); #endif int ret; sockaddr_in dest_sin; memset(&dest_sin, 0 ,sizeof(dest_sin)); dest_sin.sin_family = m_iAF; dest_sin.sin_addr.s_addr = inet_addr(serverIp); dest_sin.sin_port = htons(port); ret = ::connect(m_hSocket, (sockaddr *)&dest_sin, sizeof(dest_sin)); if( ret < 0) { #ifdef _YSDEBUG printf("error in YsSocket's Connect(%s,%d)\n",serverIp,port); #endif return false; } #ifdef _YSDEBUG printf("\t\tconnect successful!\n"); #endif return true; } /** * 绑定端口,供服务端使用 */ bool Bind(int iPort , char * sLocalIp = NULL) { #ifdef _YSDEBUG printf("into YsSocket's Bind(%d)\n",iPort); #endif int ret; sockaddr_in local_sin; local_sin.sin_family = m_iAF; local_sin.sin_addr.s_addr = sLocalIp==NULL?INADDR_ANY:inet_addr(sLocalIp); local_sin.sin_port = htons(iPort); ret = ::bind(m_hSocket, (sockaddr *)&local_sin, sizeof(local_sin)); if(ret == SOCKET_ERROR) { #ifdef _YSDEBUG printf("error in YsSocket's Bind(%s,%d)\n",sLocalIp,iPort); #endif return false; } return true; } bool Listen(int m_iBacklog=5) { #ifdef _YSDEBUG printf("into YsSocket's Listen(%d)\n",m_iBacklog); #endif int ret; ret = ::listen(m_hSocket, m_iBacklog); if(ret == SOCKET_ERROR) { #ifdef _YSDEBUG printf("error in YsSocket's Listen()\n"); #endif return false; } return true; } bool Accept(YsSocket &newSocket) { #ifdef _YSDEBUG printf("into YsSocket's Accept()\n"); #endif sockaddr_in acc_sin; int acc_sin_len=sizeof(acc_sin); SOCKET sock = ::accept(m_hSocket, (sockaddr*)&acc_sin, (socklen_t *)&acc_sin_len); if(sock == INVALID_SOCKET) { #ifdef _YSDEBUG printf("error in YsSocket's Accept()\n"); #endif return false; } newSocket.SetSocketHandle(sock); return true; } /** * 设置发送与接收的超时,0表示不限制超时 */ bool SetTimeout(int iRecvTimeout=0, int iSendTimeout=0) { printf("int SetTimeOut(%d,%d)\n",iRecvTimeout,iSendTimeout); m_iRecvTimeout = iRecvTimeout; m_iSendTimeout = iSendTimeout; /* int ret=0; if(iRecvTimeout>0) { ret = ::setsockopt(m_hSocket, SOL_SOCKET, SO_RCVTIMEO,(char*)&iRecvTimeout, sizeof(int)); } if(ret == SOCKET_ERROR) { printf("error to set SO_RCVTIMEO=%d,errno=%d, socket=%u\n",ret, errno, m_hSocket); return false; } if(iSendTimeout>0) { ret = ::setsockopt(m_hSocket, SOL_SOCKET, SO_SNDTIMEO,(char*)&iSendTimeout, sizeof(int)); } if(ret == SOCKET_ERROR) { printf("error to set SO_SNDTIMEO=%d\n",ret); return false; } */ return true; } /** * 接收指定字节的数据 * pBuffer 接收缓冲区 * iReadLen 准备读取的字节数 * flags MSG_PEEK/MSG_OOB */ int Receive(void *pBuffer, int iReadLen, int flags=0) { #ifdef _YSDEBUG printf("into YsSocket's Receive(len=%d)\n",iReadLen); #endif int iReaded=0; int ret; int times=0; while(iReaded < iReadLen) { if(!CheckForRecv()) return iReaded; ret = ::recv(m_hSocket, (char *)pBuffer+iReaded, iReadLen-iReaded,flags); if(ret <= 0) { #ifdef _YSDEBUG printf("error in YsSocket's Receive() =%d\n",ret); #endif return -1; } iReaded += ret; times++; if(times>40) break; #ifdef WIN32 Sleep(10); #else usleep(10*1000); #endif } return iReaded; } /** * 发送指定的字节 */ int Send( void *pBuffer, int iLen, int flags=0) { #ifdef _YSDEBUG printf("into YsSocket's Send(len=%d)\n",iLen); #endif if(!CheckForSend()) return -1; int ret=::send(m_hSocket, (char *)pBuffer, iLen, flags); if(ret == SOCKET_ERROR) { #ifdef _YSDEBUG printf("error in YsSocket's Send() =%d\n",ret); #endif return -1; } return ret; } /** * UDP发送指定的字节 */ int SendTo(char *sIP, int iPort, void *pBuffer, int iLen, int flags=0) { #ifdef _YSDEBUG printf("into YsSocket's SendTo(addr=%s, port=%d, len=%d)\n",sIP, iPort, iLen); #endif sockaddr_in dest_sin; memset(&dest_sin, 0 ,sizeof(dest_sin)); dest_sin.sin_family = m_iAF; dest_sin.sin_addr.s_addr = inet_addr(sIP); dest_sin.sin_port = htons(iPort); int ret = sendto(m_hSocket, (char *)pBuffer, iLen, flags, (sockaddr*)&dest_sin, sizeof(dest_sin)); if(ret == SOCKET_ERROR) { #ifdef _YSDEBUG printf("error in YsSocket's SendTo() =%d\n",ret); #endif return -1; } return ret; } bool CheckForSend() { fd_set writefds; int r; #ifdef _YSDEBUG printf("\t\tChecking for Send..\n"); #endif FD_ZERO(&writefds); FD_SET(this->m_hSocket, &writefds); // // indefinite wait select // timeval t; t.tv_sec = m_iRecvTimeout/1000; t.tv_usec = m_iRecvTimeout%1000; r = select(this->m_hSocket+1, NULL, &writefds, NULL, &t); if( r != 1) { printf("select:error\n"); Close(); return false; } return true; } bool CheckForRecv() { fd_set readfds; int r; FD_ZERO(&readfds); FD_SET(m_hSocket, &readfds); #ifdef _YSDEBUG printf("\t\tChecking for Recv..\n"); #endif timeval t; t.tv_sec = m_iRecvTimeout/1000; t.tv_usec = m_iRecvTimeout%1000; r = select(this->m_hSocket+1, &readfds, NULL, NULL, &t); if( r != 1) { printf("select:error\n"); Close(); return false; } return true; } // 等同于Receive inline int read(BYTE* dest,size_t maxLen) { return Receive(dest,maxLen); } // 等同于Send inline int write(BYTE* dest,size_t maxLen) { return Send((void*)dest,maxLen); } // 等同于Receive inline int read(char* dest,size_t maxLen) { return read((BYTE*) dest,maxLen); } // 等同于Send inline int write(char* dest,size_t maxLen) { return write((BYTE*)dest,maxLen); }};#endif /*YsSocket_H_*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -