您的位置:首页 > 编程语言 > C语言/C++

c++封装socket

2015-10-10 18:43 609 查看
lnkSocket.h

/*******************************
文件名称: lnkSocket.h
功能描述:封装socket
历史信息:lnk 创建 2015
*******************************/
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
using namespace std;

#define MAX_LINK 256

#define SOCKET_TYPE_CLIENT "client" //标记程序为客户端
#define SOCKET_TYPE_SERVER "server" //标记程序为服务端

//客户端信息 存储这些连接上来的客户信息 不知道有没有应用场景 反正我是这么想的
typedef struct tagCLIENT_INFO_T
{
int nClientFd; //接收连接后产生的套接字
struct sockaddr_in stCliAddr; //连上的客户端信息
struct tagCLIENT_INFO_T *pstNext; //下一个节点
}CLIENT_INFO_T;

//ocket封装类
class LnkSocket{
public:
LnkSocket();//构造函数 初始化客户端信息链表
LnkSocket(string sPramType, string sPramServAddr, int nPramServPort, int nPramBacklog);
void SetType(string sPramType); //设置程序是客户端还是服务端
void SetServerAddr(string sPramServAddr); //设置服务端地址
void SetServPort(int nPramServPort); //设置服务端端口
void SetBacklog(int nPramBacklog); //设置最大连接数
void CreateSocketFd(); //创建套接字 客户端connect 服务端bind、listen
int LnkAccept(struct sockaddr_in *pstCliAddr);
int LnkSend(int nPramSocketFd, const char *pcSendData, int nLen);
int LnkRecv(char *pcRecvData, int nLen);
~LnkSocket();
private:
string sType; //socket类型 服务还是客户端
int nSocketFd; //套接字
CLIENT_INFO_T *pstCliInfo; //客户端信息
string sServAddr; //服务端地址
int nServPort; //端口号
int nBacklog; //最大连接数
};
lnkSocket.cpp

#include <sys/types.h>
#include <sys/socket.h>
#include <iostream>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include "lnkSocket.h"

LnkSocket::LnkSocket()
{
this->pstCliInfo = new CLIENT_INFO_T;
memset(this->pstCliInfo, 0, sizeof(CLIENT_INFO_T));
}

LnkSocket::LnkSocket(string sPramType, string sPramServAddr, int nPramServPort, int nPramBacklog)
{
this->sType = sPramType;
this->sServAddr = sPramServAddr;
this->nServPort = nPramServPort;
this->nBacklog = nPramBacklog;
this->pstCliInfo = new CLIENT_INFO_T;
memset(this->pstCliInfo, 0, sizeof(CLIENT_INFO_T));

}

void LnkSocket::SetType(string sPramType)
{
this->sType = sPramType;
}

void LnkSocket::SetServerAddr(string sPramServAddr)
{
this->sServAddr = sPramServAddr;
}

void LnkSocket::SetServPort(int nPramServPort)
{
this->nServPort = nPramServPort;
}

void LnkSocket::SetBacklog(int nPramBacklog)
{
this->nBacklog = nPramBacklog;
}

void LnkSocket::CreateSocketFd()
{
struct sockaddr_in stServAddr;

if(this->sServAddr.length() < 8)
{
cout<<"ERROR: pleace check your server address!"<<endl;
return;
}

if(this->nServPort <= 1024)
{
cout<<"ERROR: pleace check your server port!"<<endl;
return;
}

if((this->nSocketFd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
cout<<"ERROR:create socket failed,"<<errno<<strerror(errno)<<endl;
return;
}

stServAddr.sin_family=AF_INET;
stServAddr.sin_port=htons(this->nServPort);
stServAddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(stServAddr.sin_zero),8);

if(this->sType == SOCKET_TYPE_CLIENT)
{
struct hostent *host;
if((host=gethostbyname(this->sServAddr.c_str())) == NULL)
{
cout<<"ERROR:gethostbyname failed"<<endl;
return;
}
stServAddr.sin_addr = *((struct in_addr *)host->h_addr);
//connect
if(connect(this->nSocketFd, (struct sockaddr *)&stServAddr, sizeof(struct sockaddr)) == -1)
{
cout<<"ERROR:connect to "<<this->sServAddr<<"failed!"<<errno<<strerror(errno)<<endl;
return;
}
}
else
{
// bind
if(bind(this->nSocketFd, (struct sockaddr *)&stServAddr, sizeof(struct sockaddr)) == -1)
{
cout<<"ERROR:bind to "<<this->sServAddr<<"failed!"<<errno<<strerror(errno)<<endl;
return;
}

// listen
if(listen(this->nSocketFd, this->nBacklog) == -1)
{
cout<<"ERROR:listen to "<<this->sServAddr<<"failed!"<<errno<<strerror(errno)<<endl;
return;
}
}
}

int LnkSocket::LnkAccept(struct sockaddr_in *pstCliAddr)
{
if(NULL == pstCliAddr)
{
return -1;
}
int nClientFd;
int nSinSize = sizeof(struct sockaddr_in);
if ((nClientFd = accept(this->nSocketFd, (struct sockaddr *)pstCliAddr, (socklen_t *)&nSinSize)) == -1)
{
cout<<"ERROR:accept socket failed!"<<errno<<strerror(errno)<<endl;
return -1;
}
return nClientFd;
}

int LnkSocket::LnkSend(int nPramSocketFd, const char *pcSendData, int nLen)
{
int sendNum;
if(nLen < 0 || NULL == pcSendData)
{
return -1;
}

do{
sendNum = send(nPramSocketFd, pcSendData, nLen, 0);
}while(sendNum < 0 && errno == EINTR);

return sendNum;
}

int LnkSocket::LnkRecv(char *pcRecvData, int nLen)
{
if(NULL == pcRecvData)
{
return -1;
}

return recv(this->nSocketFd, pcRecvData, nLen, 0);
}

LnkSocket::~LnkSocket()
{
close(this->nSocketFd);
}
main.cpp

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <iostream>
#include <errno.h>
#include <string.h>
//#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "lnkSocket.h"
using namespace std;
int main(int argc, char **argv)
{
LnkSocket mySK;
if(argc < 2)
{
mySK.SetType(SOCKET_TYPE_SERVER);
mySK.SetServerAddr("127.0.0.1");
}
else
{
mySK.SetType(SOCKET_TYPE_CLIENT);
mySK.SetServerAddr(argv[1]);
}
mySK.SetServPort(3333);
mySK.SetBacklog(10);
mySK.CreateSocketFd();

if(argc < 2)
{
int nCliFd;
struct sockaddr_in remote_addr;
while(1)
{
if((nCliFd = mySK.LnkAccept(&remote_addr)) == -1)
{
cout<<"ERROR:accpet failed!"<<errno<<strerror(errno)<<endl;
continue;
}
cout<<"connect from "<<inet_ntoa(remote_addr.sin_addr)<<endl;
if(!fork())
{
if(mySK.LnkSend(nCliFd, "Hello, you are connected!\n", 26) == -1)
{
cout<<"ERROR:send failed!"<<errno<<strerror(errno)<<endl;
}
close(nCliFd);
exit(0);
}
close(nCliFd);
}
}
else
{
char buf[100];
int recvbytes;
if((recvbytes=mySK.LnkRecv(buf, 100)) == -1)
{
cout<<"ERROR:recv failed!"<<errno<<strerror(errno)<<endl;
}
buf[recvbytes] = '\0';
cout<<buf<<endl;
}
return 0;
}

SConstruct文件,当然这里很多库没有用上   懒得删了

env = Environment(
CPPFLAGS = '-g -Wall -O3 -Wno-unused-result',
CFLAGS = '-g -Wall -O3 ',
CPPPATH = ['/usr/local/include', 'include', '/usr/include/mysql'],
RPATH
4000
= ['/usr/local/lib'],
LIBS = ['PocoUtil','PocoNet','PocoXML', 'PocoNetSSL','PocoFoundation','hiredis'],
LIBPATH = ['/usr/lib','/usr/local/lib']
)

env.Program(
'lnkSocket',['main.cpp','lnkSocket.cpp','lnkSocket.h'],
)

效果如下:
服务端:

xiezj@197-47:~/lnkSocket$ ./lnkSocket
connect from 127.0.0.1客户端:
xiezj@197-47:~/lnkSocket$ ./lnkSocket 127.0.0.1
Hello, you are connected!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socket c++