|
|
//: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;
|
|
|
}
|