这是个互联网时代,网络无处不在,因此有必要了解关于网络套接字编程的相关知识。
通上次一样,通过对底层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;
}