c++封装socket

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 = ['/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!


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值