You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

454 lines
8.6 KiB
C++

//:Source:8, "CServer", 39ab9146
//
// File: cserver.cpp
//
// Copyright (C) 2000 Piko, All rights reserved.
//
// Modification History:
// 29 Aug 2000, PIKO -- Generated 12:32:38 by Genitor V4.50.621.2
//
//:---------------------------------------------------------------------------
//:ClassInc
//#include "../lib_base.h"
#include "cserver.h"
#define OK 0
#define FAIL __LINE__
#define DebugOutLn //
//:Include
//#include "ach.h"
#if defined(_UNIX)
#include <unistd.h>
#include <memory.h>
#else
#ifdef _WIN32_WCE
#else
#include <time.h>
#endif
#endif // defined(_UNIX)
#include <time.h>
#include <stdio.h>
int Init(int handle)
{
/*
* Force an immediate termination of the connection when closing it
*/
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
if(setsockopt (handle, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof(linger)) != 0)
{
DebugOutLn("failed to set socket option");
};
/*
* Force nonblocking
*/
#ifdef _UNIX
return fcntl( handle, F_SETFL, O_NONBLOCK|O_NOCTTY );
#else
unsigned long Arg1=1;
return ioctlsocket(handle, FIONBIO, &Arg1);
#endif
}
//:> +-----------------------------------+
//:>------------------| Member Function Definitions |-------------------
//:> +-----------------------------------+
//::1
// +-----------------------+
// | Default Constructor |
// +-----------------------+
CServer::CServer()
{
m_clientlistensock=INVALID;
m_clientlistenport=0;
m_lasterror=0;
m_starttime=0;
#ifndef _UNIX
/*
* Setup Winsock 1.1
*/
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1) {
DebugOutLn("winsock too old");
WSACleanup();
exit(1);
}
#endif
}
//::2
// +--------------+
// | Destructor |
// +--------------+
CServer::~CServer()
{
CloseServer();
#ifndef _UNIX
// Cleanup Winsock
WSACleanup();
#endif
}
//::3
// +-----------------+
// | CloseServer() |
// +-----------------+
void CServer::CloseServer()
{
if(m_clientlistensock)closesocket(m_clientlistensock);
m_clientlistensock=INVALID;
}
//::7
// +----------+
// | Dump() |
// +----------+
//::4
// +------------------+
// | GetLastError() |
// +------------------+
int CServer::GetLastError()
{
return m_lasterror;
}
//::5
// +-------------+
// | StartUp() |
// +-------------+
void CServer::StartUp(
int p_port,
bool p_udp ) // serverport f<>r die windows clients
{
m_lasterror=0;
int rc;
struct sockaddr_in SrvAdr;
//Existierenden socket schlie<69>en
if(m_clientlistensock!=INVALID) CloseServer();
//neuen Port eintragen, socket erstellen
m_clientlistenport = p_port;
if( p_udp )
m_clientlistensock = socket(AF_INET, SOCK_DGRAM, 0);
else
m_clientlistensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(m_clientlistensock == -1 )
{
/*
Log << ID
<< "failed, cannot create socket"
;
Log.flush(LOGFILE|LOGERR);
*/
DebugOutLn("cannot create listen port %d",m_clientlistenport);
m_lasterror=-1;
}
else
{
SrvAdr.sin_family = AF_INET;
SrvAdr.sin_port = htons(m_clientlistenport);
SrvAdr.sin_addr.s_addr = 0;
memset(SrvAdr.sin_zero, 0, sizeof(SrvAdr.sin_zero));
rc = bind(m_clientlistensock, (struct sockaddr *)&SrvAdr, sizeof(SrvAdr));
if(rc)
{
closesocket(m_clientlistensock);
m_clientlistensock=INVALID;
//cerr << timestamp()
// << ID
// << "failed, cannot bind to port "
// << m_clientlistenport
// << endl
// << flush;
DebugOutLn("cannot bind socket to port %d",m_clientlistenport);
m_lasterror=rc;
}
else
{
if( p_udp )
{
#ifdef _UNIX
m_lasterror = fcntl( m_clientlistensock, F_SETFL, O_NONBLOCK|O_NOCTTY );
#else
unsigned long Arg1=1;
m_lasterror = ioctlsocket(m_clientlistensock, FIONBIO, &Arg1);
#endif
}
else
{
//ab jetzt liegt der socket auf listen
m_lasterror = listen(m_clientlistensock, SOMAXCONN);
}
/*
Log
<< ID
<< "successfull, listening at port "
<< m_clientlistenport;
Log.flush();
*/
m_starttime=time(0);
}
}
}
int CServer::StartUpAsClient(unsigned int ipaddr, int port, bool p_udp)
{
m_lasterror=0;
int rc=0;
struct sockaddr_in my_addr;
unsigned long inaddr = 0;
//struct hostent *hp;
/*
* Setup basics about server address
*/
memset((char *) &m_destaddr, 0, sizeof(m_destaddr));
m_destaddr.sin_family = AF_INET;
// m_destaddr.sin_addr.S_un.S_addr = htonl(ipaddr);
m_destaddr.sin_addr.s_addr = htonl(ipaddr);
m_destaddr.sin_port = htons((u_short) port );
/*
* socket <20>ffnen
*/
if( p_udp ){
if ((m_clientlistensock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
if(rc) {
//"open socket failed";
DebugOutLn("open socket failed");
return -1;
}
}
else{ // tcp
if ((m_clientlistensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
if(rc) {
DebugOutLn("open socket failed");
return -1;
}
}
if( p_udp == true ){
/*
* Setup client address
*/
memset((char *) &my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
my_addr.sin_port = htons((u_short) 0 );
rc = bind(m_clientlistensock, (struct sockaddr *)&my_addr, sizeof(my_addr));
if(rc) {
DebugOutLn("cannot bind port");
return -1; //throw "cannot bind to port";
}
{
/*
Log << "failed, " << msg ;
Log.flush(LOGFILE|LOGERR);
*/
}
/*Log << ID
<< port
<< " successfull"
;
Log.flush();
*/
}
else
{
memset((char *) &my_addr, 0, sizeof(my_addr));
my_addr.sin_addr.s_addr = m_destaddr.sin_addr.s_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(port);
if (connect(m_clientlistensock, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
DebugOutLn("connect failed");
return -1;//"connect failed";
}
Init( m_clientlistensock );
}
return m_lasterror;
}
int CServer::StartUpAsClient(const char *ipaddr, int port, bool p_udp)
{
m_lasterror=0;
int rc=0;
struct sockaddr_in my_addr;
unsigned long inaddr = 0;
struct hostent *hp;
/*
* Setup basics about server address
*/
memset((char *) &m_destaddr, 0, sizeof(m_destaddr));
m_destaddr.sin_family = AF_INET;
m_destaddr.sin_port = htons((u_short) port );
//Ipadresse eintragen
if ( (inaddr = inet_addr(ipaddr) != INADDR_NONE) ) {
//memcpy((char *) &m_destaddr.sin_addr, (char *) &inaddr, sizeof(inaddr));
int ipadr,ip1,ip2,ip3,ip4;
if( 4 == sscanf(ipaddr,"%d.%d.%d.%d",&ip1,&ip2,&ip3,&ip4)){
ipadr = (ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
m_destaddr.sin_addr.s_addr = htonl(ipadr);
}
else{
DebugOutLn("gethostbyname(%s) failed",ipaddr);
m_lasterror = -1;
return -1;
}
} else {
if ( (hp = gethostbyname(ipaddr)) == NULL) {
DebugOutLn("gethostbyname(%s) failed",ipaddr);
m_lasterror = -1;
return -1;
}
memcpy((char *) &m_destaddr.sin_addr, hp->h_addr, hp->h_length);
}
/*
* socket <20>ffnen
*/
if( p_udp ){
if ((m_clientlistensock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
if(rc) {
DebugOutLn("open socket failed");
return -1;
}
}
else{ // tcp
if ((m_clientlistensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
if(rc) {
DebugOutLn("open socket failed");
return -1;
}
}
if( p_udp == true ){
/*
* Setup client address
*/
memset((char *) &my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
my_addr.sin_port = htons((u_short) 0 );
rc = bind(m_clientlistensock, (struct sockaddr *)&my_addr, sizeof(my_addr));
if(rc) {
m_lasterror = -1;
DebugOutLn("cannot bind port");
return -1; //throw "cannot bind to port";
}
{
/*
Log << "failed, " << msg ;
Log.flush(LOGFILE|LOGERR);
*/
}
/*Log << ID
<< port
<< " successfull"
;
Log.flush();
*/
}
else
{
memset((char *) &my_addr, 0, sizeof(my_addr));
my_addr.sin_addr.s_addr = m_destaddr.sin_addr.s_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(port);
if (connect(m_clientlistensock, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
DebugOutLn("connect failed");
return -1;//"connect failed";
}
Init( m_clientlistensock );
}
return m_lasterror;
}
int CServer::Write(char * buf,int cnt)
{
/*if( Prefs.m_master )
return 0;
*/
/////DebugOutLn("Write(%d): %s",cnt,buf);
if( cnt == 0 )
cnt = strlen(buf) + 1;
int bytes = sendto(m_clientlistensock,buf,cnt,0,(sockaddr*)&m_destaddr,sizeof(m_destaddr));
if( bytes != cnt )
{
/*
Log << "error, send to master failed";
Log.flush(LOGERR);
*/
}
return bytes;
}