万丈高楼平地起之socket篇

本文介绍了一个基于WinSock的网络套接字编程封装类,包括客户端和服务端的实现细节。通过对基本socket函数的封装,简化了网络通信的流程,并提供了易于使用的接口。

这是个互联网时代,网络无处不在,因此有必要了解关于网络套接字编程的相关知识。

通上次一样,通过对底层socket的封装,加深理解,同时在以后的使用中会得心应手。


头文件:

#ifndef _H_S_BASE_H_
#define _H_S_BASE_H_
#include <winsock2.h>

#pragma comment(lib,"ws2_32.lib")
class CSBase
{
public:
	CSBase();
	~CSBase();
public:
	bool SBCreate();
	bool SBDestroy();
	
	bool SBBind(UINT nType,UINT nPort);
	bool SBUnbind();
	
	bool SBListen(int nMaxClients = 1024);
	bool SBAccept(SOCKET &sockClient,UINT &remoteIP,UINT &remotePort);
	bool SBConnect(const char* pRemoteIP,UINT nPort);
	
	bool SBSend(const char* pData,int nDataLength,int &nRealSend);
	bool SBReceive(char* pData,int nSize,int &nRealRecv);
	
	bool SBBlock(bool bBlock);
	bool SBBlock();

    SOCKET SBGetSocket();
    void   SBSetSocket(SOCKET localsock);
public:
	SOCKET m_socket;
};

#endif

源文件

#include "SBase.h"

#pragma comment(lib,"ws2_32.lib")

CSBase::CSBase()
{
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2,2),&wsadata);
}

CSBase::~CSBase()
{
	WSACleanup();
}

bool CSBase::SBCreate()
{
	m_socket = socket(AF_INET,SOCK_STREAM,0);

	if(m_socket == -1)
		return false;
	return true;
}

bool CSBase::SBDestroy()
{
	closesocket(m_socket);
	m_socket = -1;
	return true;
}

bool CSBase::SBBind(UINT nType, UINT nPort)
{
	struct sockaddr_in inaddr;
	inaddr.sin_family = AF_INET;
	inaddr.sin_port = htons(nPort);
	inaddr.sin_addr.s_addr = INADDR_ANY;
	
	int nResult = bind(m_socket,(struct sockaddr*)&inaddr,sizeof(inaddr));
	
	if(nResult != 0)
		return false;
	return true;
}

bool CSBase::SBUnbind()
{
	return true;
}

bool CSBase::SBListen(int nMaxClient)
{
	int nResult = listen(m_socket,nMaxClient);
	
	if(nResult != 0)
		return false;
	return true;
}

bool CSBase::SBAccept(SOCKET &sockClient,UINT &remoteIP,UINT &remotePort)
{
	struct sockaddr_in inaddr;
	memset(&inaddr,0,sizeof(struct sockaddr_in));
	int nSize = sizeof(struct sockaddr_in);
	
	sockClient = accept(m_socket,(struct sockaddr*)&inaddr,&nSize);
	
	if(sockClient ==-1)
		return false;
		
	remoteIP = ntohs(inaddr.sin_addr.s_addr);
	remotePort = ntohs(inaddr.sin_port);
	return true;
}

bool CSBase::SBConnect(const char* pRemoteIP,UINT nPort)
{
	struct sockaddr_in inaddr;
	inaddr.sin_family = AF_INET;
	inaddr.sin_port   = htons(nPort);
	inaddr.sin_addr.s_addr = inet_addr(pRemoteIP);
	int nResult = connect(m_socket,(struct sockaddr*)&inaddr,sizeof(struct sockaddr_in));
	if(nResult != 0)
		return false;
	return true;	
}

bool CSBase::SBSend(const char* pData,int nDataLength,int &nRealSend)
{
	nRealSend = send(m_socket,pData,nDataLength,0);
	if(nRealSend == -1)
		return false;
	return true;
}

bool CSBase::SBReceive(char* pData,int nSize,int &nRealRecv)
{
	nRealRecv = recv(m_socket,pData,nSize,0);
	if(nRealRecv == -1)
		return false;
	return true;
}

bool CSBase::SBBlock(bool bBlock)
{
	u_long iMode;
	if(bBlock)
		iMode = 0;
	else
		iMode = 1;
	int nResult = ioctlsocket(m_socket,FIONBIO,&iMode);
	
	if(nResult != 0)
		return false;
	return true;
}

bool CSBase::SBBlock()
{
    return true;
}

SOCKET CSBase::SBGetSocket()
{
    return m_socket;
}

void CSBase::SBSetSocket( SOCKET localsock )
{
    m_socket = localsock;
}

通过对其封装,认识到将一些小的代码段,拼接成一个类,提供其功能接口,供以后调用,很方便。

在封装了最基本的socket函数后,又进行了一次封装,区分出server和client

其实现代码为:

client端:

#ifndef _H_TCP_CLIENT_H_
#define _H_TCP_CLIENT_H_

#include "SBase.h"

class CTCPClient : public CSBase
{
public:
    CTCPClient(void);
    ~CTCPClient(void);
public:
    bool TCPConnect(const char* pRemoteIP,UINT nPort);
    bool TCPUnconnect();

    int  TCPSend(const char* pData,int nDataLength);
    int  TCPRecv(char* pData,int nDataRecv);
};

#endif

#include "TCPClient.h"

CTCPClient::CTCPClient(void)
{
}

CTCPClient::~CTCPClient(void)
{
}

bool CTCPClient::TCPConnect( const char* pRemoteIP,UINT nPort )
{
    bool bRet = false;
    if (SBCreate())
    {
        if (SBConnect(pRemoteIP,nPort))
        {
            bRet = true;
        }
    }
    return bRet ;
}

bool CTCPClient::TCPUnconnect()
{
    SBDestroy();
    return true;
}

int CTCPClient::TCPSend( const char* pData,int nDataLength )
{
    int nRealSend;
    SBSend(pData,nDataLength,nRealSend);
    return nRealSend;
}

int CTCPClient::TCPRecv( char* pData,int nSize )
{
    int nDataRecv;
    SBReceive(pData,nSize,nDataRecv);
    return nDataRecv;
}

server端:

#ifndef _H_TCP_SERVER_H_
#define _H_TCP_SERVER_H_

#include "SBase.h"
class CTCPServer : public CSBase
{
public:
    CTCPServer(void);
    ~CTCPServer(void);

public:
    bool TCPStart(int nPort);
    bool TCPStop();

    SOCKET TCPAccept(UINT &remoteIP,UINT &remotePort);

    int  TCPSend(const char* pData,int nDataLength);
    int  TCPRecv(char* pData,int nDataRecv);

};

#endif

#include "TCPServer.h"
#include <stdio.h>
CTCPServer::CTCPServer(void)
{
}

CTCPServer::~CTCPServer(void)
{
}

bool CTCPServer::TCPStart( int nPort )
{
    bool bReturn = false;
    if (SBCreate())
    {
        if (SBBind(0,nPort))
        {
            if (SBListen())
            {
                //TBCreateThread(CTBase::TBRUNNING);
                //return true;
                bReturn = true;
            }
        }
    }
    return bReturn;

}

bool CTCPServer::TCPStop()
{

    SBDestroy();
    return true;
}

SOCKET CTCPServer::TCPAccept(UINT &remoteIP,UINT &remotePort)
{
    //printf("1\n\r");
    SOCKET sockClient = -1;
    SBAccept(sockClient,remoteIP,remotePort);
    return sockClient;
    return true;
}

int CTCPServer::TCPSend( const char* pData,int nDataLength )
{
    int nSendLenghth = -1;
    
    SBSend(pData,nDataLength,nSendLenghth);
    
    return nSendLenghth;
}

int CTCPServer::TCPRecv( char* pData,int nDataRecv )
{
    int nRecvLength = -1;

    SBReceive(pData,nDataRecv,nRecvLength);

    return nRecvLength;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值