把socket的一些函式封裝
//TcpClient.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/select.h>
#include <netdb.h>
class TcpClient
{
private:
int m_sockfd;
char m_ip[21];
int m_port;
bool m_btimeout; //Read/Write是否是因為超時而返回false,超時為true
int m_bufferlen;
public:
TcpClient();
~TcpClient();
bool ConnectServer(const char* ip, int port);
bool Readn(const int sockfd, char* buffer, const size_t n);
bool Writen(const int sockfd, char* buffer, const size_t n);
bool TcpRead(int sockfd, char* buffer, int* ibuflen, const int timeout=0);
bool TcpWrite(int sockfd, char* buffer, int* ibuflen=0);
bool Read(char* buffer, const int timeout);
bool Write(char* buffer, int ibuflen=0);
void Close();
};
//TcpClient.cpp
#include "TcpClient.h"
TcpClient::TcpClient()
{
m_sockfd=-1;
memset(m_ip, 0, sizeof(m_ip));
m_port=0;
m_btimeout=false;
m_bufferlen=0;
}
TcpClient::~TcpClient()
{
Close();
}
bool TcpClient::ConnectServer(const char* ip, int port)
{
if(m_sockfd != -1)
{
Close();
}
//memcpy(m_ip, ip, sizeof(ip));
strcpy(m_ip,ip);
m_port=port;
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
/*
struct hostent* host;
if(!(host = gethostbyname(m_ip))) //dns解析
{
Close();
return false;
}
memcpy(&server_addr.sin_addr, &host->h_addr, host->h_length);
*/
server_addr.sin_addr.s_addr=inet_addr(m_ip);
server_addr.sin_port=htons(m_port);
m_sockfd = socket(PF_INET, SOCK_STREAM, 0);
if(m_sockfd==-1)
{
return false;
}
if(connect(m_sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
{
Close();
return false;
}
return true;
}
bool TcpClient::Readn(const int sockfd, char* buffer, const size_t n)
{
if(sockfd==-1 || NULL==buffer) return false;
int nleft,nread,idx;
nleft=n;
nread=0;
idx=0;
while(nleft>0)
{
if((nread = recv(sockfd, buffer+idx, nleft, 0))<=0)
{
fprintf(stderr, "Error: %s\n", strerror(errno));
return false;
}
nleft-=nread;
idx+=nread;
}
return true;
}
bool TcpClient::Writen(const int sockfd, char* buffer, const size_t n)
{
if(sockfd==-1 || NULL==buffer) return false;
int nleft,nwrite,idx;
nleft=n;
nwrite=0;
idx=0;
while(nleft>0)
{
if((nwrite = send(sockfd, buffer+idx, nleft, 0))<=0)
{
fprintf(stderr, "Error: %s\n", strerror(errno));
return false;
}
nleft-=nwrite;
idx+=nwrite;
}
return true;
}
bool TcpClient::TcpRead(int sockfd, char* buffer, int* ibuflen, const int timeout)
{
if(sockfd==-1 || NULL==buffer || NULL==ibuflen) return false;
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(sockfd,&tmpfd);
struct timeval ttimeout;
ttimeout.tv_sec=timeout;
ttimeout.tv_usec=0;
int i;
if((i=select(sockfd+1,0,&tmpfd,0,&ttimeout))<=0) return false;
(*ibuflen)=0;
if(Readn(sockfd,(char*)ibuflen,4)==false) return false; //讀取資料長度到ibuflen
(*ibuflen)=ntohl(*ibuflen); //ibuflen轉主機序
if(Readn(sockfd, buffer, (*ibuflen))==false) return false;
return true;
}
bool TcpClient::TcpWrite(int sockfd, char* buffer, int* ibuflen)
{
if(sockfd==-1 || NULL==buffer || NULL==ibuflen) return false;
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(sockfd,&tmpfd);
struct timeval timeout;
timeout.tv_sec=5;
timeout.tv_usec=0;
if(select(sockfd+1,0,&tmpfd,0,&timeout)<=0) return false;
int ilen=1;
if(ibuflen==0) ilen=strlen(buffer); //ibuflen==0設為寫入的是字串
else ilen=*ibuflen; //ibuflen!=0設為寫入二進位制資料
int ilenn=htonl(ilen);
char strBufferTmp[ilen+4]; //儲存長度+資料資料包
memset(strBufferTmp,0,ilen+4);
memcpy(strBufferTmp,&ilenn,4); //存長度
memcpy(strBufferTmp+4,buffer,ilen); //存資料
if(Writen(sockfd, strBufferTmp, ilen+4) == false) return false;
return true;
}
bool TcpClient::Read(char* buffer, const int timeout)
{
if(m_sockfd==-1) return false;
if(timeout>0)
{
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(m_sockfd,&tmpfd);
struct timeval _timeout;
_timeout.tv_sec=timeout;
_timeout.tv_usec=0;
m_btimeout=false;
int i;
if((i=select(m_sockfd+1,0,&tmpfd,0,&_timeout))<=0)
{
if(i==0)
m_btimeout=true;
return false;
}
}
m_bufferlen=0;
return TcpRead(m_sockfd, buffer, &m_bufferlen);
}
bool TcpClient::Write(char* buffer, int ibuflen)
{
if(m_sockfd==-1) return false;
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(m_sockfd,&tmpfd);
struct timeval timeout;
timeout.tv_sec=5;
timeout.tv_usec=0;
int i;
if((i=select(m_sockfd+1,0,&tmpfd,0,&timeout))<=0)
{
if(i==0)
m_btimeout=true;
return false;
}
int ilen=ibuflen;
if(ilen==0)
ilen=strlen(buffer);
return TcpWrite(m_sockfd, buffer, &ilen);
}
void TcpClient::Close()
{
close(m_sockfd);
m_sockfd=-1;
}
//TcpServer.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/select.h>
#include <errno.h>
class TcpServer
{
private:
struct sockaddr_in m_server_addr;
struct sockaddr_in m_client_addr;
int m_client_addr_size;
public:
int m_listenBacklog=100;
unsigned int m_port;
int m_listenfd;
int m_clientfd;
bool m_btimeout;
int m_bufferlen;
public:
TcpServer();
~TcpServer();
bool InitServer(const unsigned int port);
bool Accept();
bool Readn(const int sockfd, char* buffer, const size_t n);
bool Writen(const int sockfd, char* buffer, const size_t n);
bool TcpRead(int sockfd, char* buffer, int* ibuflen, const int timeout=0);
bool TcpWrite(int sockfd, char* buffer, int* ibuflen=0);
bool Read(char* buffer, const int timeout=0);
bool Write(char* buffer, int ibuflen=0);
char* GetIP();
void CloseListen();
void CloseClient();
};
//TcpServer.cpp
#include "TcpServer.h"
TcpServer::TcpServer()
{
m_port=-1;
m_listenfd=-1;
m_client_addr_size=0;
m_bufferlen=0;
m_btimeout=false; //Read/Write是否是因為超時而返回false,超時為true
}
TcpServer::~TcpServer()
{
CloseListen();
CloseClient();
}
bool TcpServer::InitServer(const unsigned int port)
{
if(m_listenfd>0)
{
close(m_listenfd);
m_listenfd=-1;
}
m_listenfd = socket(PF_INET, SOCK_STREAM, 0);
if(m_listenfd == -1) return false;
int opt=1;
unsigned int len=sizeof(opt);
setsockopt(m_listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, len);
memset(&m_server_addr, 0, sizeof(m_server_addr));
m_server_addr.sin_family=AF_INET;
m_server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
m_server_addr.sin_port=htons(port);
if(bind(m_listenfd, (struct sockaddr*) &m_server_addr, sizeof(m_server_addr)) == -1)
{
CloseListen();
return false;
}
if(listen(m_listenfd, m_listenBacklog) == -1)
{
CloseListen();
return false;
}
m_client_addr_size=sizeof(m_client_addr);
return true;
}
bool TcpServer::Accept()
{
if(m_listenfd == -1) return false;
if((m_clientfd = accept(m_listenfd, (struct sockaddr*)&m_client_addr,(socklen_t*)&m_client_addr_size)) == -1) return false;
return true;
}
bool TcpServer::Readn(const int sockfd, char* buffer, const size_t n)
{
if(sockfd==-1 || NULL==buffer) return false;
int nleft,nread,idx;
nleft=n;
nread=0;
idx=0;
while(nleft>0)
{
if((nread = recv(sockfd, buffer+idx, nleft, 0))<=0)
{
fprintf(stderr, "Error: %s\n", strerror(errno));
return false;
}
nleft-=nread;
idx+=nread;
}
return true;
}
bool TcpServer::Writen(const int sockfd, char* buffer, const size_t n)
{
if(sockfd==-1 || NULL==buffer) return false;
int nleft,nwrite,idx;
nleft=n;
nwrite=0;
idx=0;
while(nleft>0)
{
if((nwrite = send(sockfd, buffer+idx, nleft, 0))<=0)
{
fprintf(stderr, "Error: %s\n", strerror(errno));
return false;
}
nleft-=nwrite;
idx+=nwrite;
}
return true;
}
bool TcpServer::TcpRead(int sockfd, char* buffer, int* ibuflen, const int timeout)
{
if(sockfd==-1 || NULL==buffer || NULL==ibuflen) return false;
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(sockfd,&tmpfd);
struct timeval ttimeout;
ttimeout.tv_sec=timeout;
ttimeout.tv_usec=0;
int i;
if((i=select(sockfd+1,0,&tmpfd,0,&ttimeout))<=0) return false;
(*ibuflen)=0;
if(Readn(sockfd,(char*)ibuflen,4)==false) return false;
(*ibuflen)=ntohl(*ibuflen);
if(Readn(sockfd, buffer, (*ibuflen))==false) return false;
return true;
}
bool TcpServer::TcpWrite(int sockfd, char* buffer, int* ibuflen)
{
if(sockfd==-1 || NULL==buffer || NULL==ibuflen) return false;
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(sockfd,&tmpfd);
struct timeval timeout;
timeout.tv_sec=5;
timeout.tv_usec=0;
if(select(sockfd+1,0,&tmpfd,0,&timeout)<=0) return false;
int ilen=1;
if(ibuflen==0) ilen=strlen(buffer);
else ilen=*ibuflen;
int ilenn=htonl(ilen);
char strBufferTmp[ilen+4];
memset(strBufferTmp,0,ilen+4);
memcpy(strBufferTmp,&ilenn,4);
memcpy(strBufferTmp+4,buffer,ilen);
if(Writen(sockfd, strBufferTmp, ilen+4) == false) return false;
return true;
}
bool TcpServer::Read(char* buffer, const int timeout)
{
if(m_clientfd==-1) return false;
if(timeout>0)
{
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(m_clientfd,&tmpfd);
struct timeval _timeout;
_timeout.tv_sec=timeout;
_timeout.tv_usec=0;
m_btimeout=false;
int i;
if((i=select(m_clientfd+1,0,&tmpfd,0,&_timeout))<=0)
{
if(i==0)
m_btimeout=true;
return false;
}
}
m_bufferlen=0;
return TcpRead(m_clientfd, buffer, &m_bufferlen);
}
bool TcpServer::Write(char* buffer, int ibuflen)
{
if(m_clientfd==-1) return false;
fd_set tmpfd;
FD_ZERO(&tmpfd);
FD_SET(m_clientfd,&tmpfd);
struct timeval timeout;
timeout.tv_sec=5;
timeout.tv_usec=0;
int i;
if((i=select(m_clientfd+1,0,&tmpfd,0,&timeout))<=0)
{
if(i==0)
m_btimeout=true;
return false;
}
int ilen=ibuflen;
if(ilen==0)
ilen=strlen(buffer);
return TcpWrite(m_clientfd, buffer, &ilen);
}
char* TcpServer::GetIP()
{
return inet_ntoa(m_client_addr.sin_addr);
}
void TcpServer::CloseListen()
{
close(m_listenfd);
m_listenfd=-1;
}
void TcpServer::CloseClient()
{
close(m_clientfd);
m_clientfd=-1;
}