Files
itgmania212121/stepmania/src/ezsockets.cpp
T

426 lines
7.4 KiB
C++
Raw Normal View History

/*******************************************
ezsockets.cpp -- Header for sockets.cpp
Designed by Josh Allen and Charles
Lohr. Socket programming methods based
on Charles Lohr's EZW progam.
You may freely destribute this code
if this message is retained.
This code is distributed on an as-is
basis with no gaurentees whatsoever.
Modified by Charles Lohr for use with
Windows-Based OSes.
********************************************/
// We need the WinSock32 Library on Windows
2004-05-24 19:38:22 +00:00
#include "global.h"
#include "ezsockets.h"
#if defined(WIN32)
#pragma comment(lib,"wsock32.lib")
2004-03-17 06:05:52 +00:00
#endif
EzSockets::EzSockets()
{
MAXCON = 5;
memset ( &addr, 0, sizeof(addr) ); //Clear the sockaddr_in structure
// Windows REQUIRES WinSock Startup
#if defined(WIN32)
WSAStartup( MAKEWORD(1,1), &wsda );
#endif
sock = -1;
blocking=true;
scks = new fd_set;
times = new timeval;
times->tv_sec = 0;
times->tv_usec = 0;
state = skDISCONNECTED;
}
EzSockets::~EzSockets()
{
close();
}
bool EzSockets::check()
{
//Check to see if the socket has been created
if ( sock < 0 )
return false;
return true;
}
int EzSockets::create()
{
state = skDISCONNECTED;
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
return (true);
}
bool EzSockets::bind( unsigned short port )
{
if ( !check() )
return false;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl( INADDR_ANY );
addr.sin_port = htons( port );
int desc = ::bind( sock, (struct sockaddr *)&addr, sizeof(addr) );
if ( desc < 0 )
return false;
return true;
}
bool EzSockets::listen()
{
int desc = ::listen( sock, MAXCON );
if ( desc < 0 )
return false;
state = skLISTENING;
return true;
}
// glibc already has socklen_t defined
// to whoever edited this:
// please do not assume LINUX is defined if you're compiling on linux!
// it will not compile properly.
2004-04-06 07:23:36 +00:00
#if defined(WIN32) || defined(DARWIN)
typedef int socklen_t;
#endif
bool EzSockets::accept( EzSockets &socket )
{
// Windows wants it defined as a signed int
// As does everything else -- Steve
int length = sizeof( socket );
socket.sock = ::accept( sock, (struct sockaddr *)&socket.addr,(socklen_t *)&length );
socket.state = skCONNECTED;
if ( socket.sock < 0 )
return false;
return true;
}
void EzSockets::close() {
state = skDISCONNECTED;
inBuffer = "";
outBuffer = "";
// The close socket command is different in Windows
#if defined(WIN32)
::closesocket( sock );
#else
::close( sock );
#endif
}
long EzSockets::uAddr()
{
return addr.sin_addr.s_addr;
}
bool EzSockets::connect( const std::string& host, unsigned short port )
{
if (! check() )
return false;
#if defined(WIN32)
struct hostent* phe;
addr.sin_family = AF_INET;
addr.sin_port = htons( port );
phe = gethostbyname( host.c_str() );
addr.sin_addr = *( (LPIN_ADDR)*phe->h_addr_list );
int desc = ::connect( sock, (struct sockaddr *)&addr, sizeof(addr) );
#else
addr.sin_family = AF_INET;
addr.sin_port = htons( port );
inet_pton( AF_INET, host.c_str(), &addr.sin_addr );
int desc = ::connect( sock, (struct sockaddr *)&addr, sizeof(addr) );
#endif
return desc >= 0;
}
bool EzSockets::CanRead()
{
FD_ZERO(scks);
2004-05-24 19:38:22 +00:00
FD_SET((unsigned)sock,scks);
if (select (0,scks,NULL,NULL,times)==0)
return false;
return true;
}
bool EzSockets::IsError()
{
if (state == skERROR)
return true;
FD_ZERO(scks);
2004-05-24 19:38:22 +00:00
FD_SET((unsigned)sock,scks);
if (select (0,NULL,NULL,scks,times)==0)
return false;
return true;
}
bool EzSockets::CanWrite()
{
FD_ZERO(scks);
2004-05-24 19:38:22 +00:00
FD_SET((unsigned)sock,scks);
if (select (0,NULL,scks,NULL,times)==0)
return false;
return true;
}
void EzSockets::update()
{
if (state==skERROR)
return;
//If socket is in error, don't bother.
if (IsError())
{
state=skERROR;
return;
}
//Check for reading
while (CanRead() && !IsError())
pUpdateRead();
if (CanWrite() && (outBuffer.length()>0))
pUpdateWrite();
}
//Raw data system
void EzSockets::SendData(string & outData)
{
outBuffer.append(outData);
if (blocking)
while ((outBuffer.length()>0) && !IsError())
pUpdateWrite();
else
update();
}
void EzSockets::SendData(const char *data, unsigned int bytes)
{
outBuffer.append(data,bytes);
if (blocking)
while ((outBuffer.length()>0) && !IsError())
pUpdateWrite();
else
update();
}
int EzSockets::ReadData(char *data, unsigned int bytes)
{
int bytesRead = PeekData(data,bytes);
inBuffer = inBuffer.substr(bytesRead);
return bytesRead;
}
int EzSockets::PeekData(char *data, unsigned int bytes)
{
if (blocking)
while ((inBuffer.length()<bytes) && !IsError())
pUpdateRead();
else
{
while (CanRead()&&!IsError())
pUpdateRead();
}
int bytesRead = bytes;
if (inBuffer.length()<bytes)
bytesRead = inBuffer.length();
memcpy(data,(inBuffer.substr(0,bytesRead)).c_str(),bytesRead);
return bytesRead;
}
//Packet system (for structures and classes)
void EzSockets::SendPack(char * data, unsigned int bytes)
{
SendData ((char *)&bytes,sizeof(int));
SendData (data,bytes);
}
int EzSockets::ReadPack(char * data, unsigned int max)
{
int size = PeekPack(data,max);
if (size!=-1)
{
int tSize = (int)((inBuffer.substr(0,4)).c_str());
inBuffer = inBuffer.substr(tSize+4);
}
return size;
}
int EzSockets::PeekPack(char * data, unsigned int max)
{
if (CanRead())
pUpdateRead();
if (blocking)
{
while ((inBuffer.length()<4)&& !IsError())
{
pUpdateRead();
}
unsigned int size=0;
PeekData((char*)size,4);
while ((inBuffer.length()<(size+4)) && !IsError())
{
pUpdateRead();
}
string tBuff(inBuffer.substr(4,size));
if (tBuff.length()>max)
tBuff.substr(0,max);
memcpy (data,tBuff.c_str(),tBuff.length());
return (size);
}
else
if (inBuffer.length()>3)
{
unsigned int size=0;
PeekData((char*)size,4);
if (inBuffer.length()<(size+4))
return (-1);
string tBuff(inBuffer.substr(4,size));
if (tBuff.length()>max)
tBuff.substr(0,max);
memcpy (data,tBuff.c_str(),tBuff.length());
return (size);
} else
return (-1);
}
//String (Flash) system / Null-terminated strings
void EzSockets::SendStr(string & data, char delim)
{
char tDr[1];
tDr[0] = delim;
SendData(data.c_str(),data.length());
SendData(tDr,1);
}
int EzSockets::ReadStr(string & data, char delim)
{
int t = PeekStr (data, delim);
if (t!=-1)
inBuffer = inBuffer.substr(t+1);
return t;
}
int EzSockets::PeekStr(string & data, char delim)
{
int t;
t = inBuffer.find(delim,0);
if (blocking)
{
while ((t==-1) && !IsError())
{
pUpdateRead();
t = inBuffer.find(delim,0);
}
data = inBuffer.substr(0,t);
}else{
if (t == -1)
return -1;
data = inBuffer.substr(0,t);
}
return t;
}
int EzSockets::pUpdateRead()
{
char tempData[1024];
int bytes = pReadData(tempData);
if (bytes>0)
inBuffer.append(tempData,bytes);
//You cannot read 0 bytes!
if (bytes<1)
state = skERROR;
return bytes;
}
int EzSockets::pUpdateWrite()
{
int bytes = pWriteData(outBuffer.c_str(),outBuffer.length());
outBuffer = outBuffer.substr(bytes);
return bytes;
}
int EzSockets::pReadData(char * data)
{
return recv( sock, data,1024, 0 );
}
int EzSockets::pWriteData(const char * data, int dataSize)
{
return send( sock, data, dataSize, 0 );
}
istream& operator >>(istream &is,EzSockets &obj)
{
string writeString;
obj.SendStr(writeString);
is>>writeString;
return is;
}
ostream& operator <<(ostream &os, EzSockets &obj)
{
string readString;
obj.ReadStr(readString);
os<<readString;
return os;
}