/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- csocket
- csocket
- csocket
- set_active
- get_active
- send_receive
- send_receive
- close_socket
- recv_data
- send_data
- client_connect
/* Client socket class for TCP connection oriented IPC.
Rick Smereka, Copyright (C) 2000-2002.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, get a copy via the Internet at
http://gnu.org/copyleft/gpl.html or write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
You can contact the author via email at rsmereka@future-lab.com.
Original version for Unix and Windows 32-bit.
Aug/2000, Rick Smereka
Added 'using namespace std'. Dec/2002, RIck Smereka */
#include "stdhead.h"
#include "flsocket.h"
#include "csocket.h"
using namespace std;
csocket::csocket()
{
// No parameter constructor.
client_hostname = "";
client_port = 0;
client_init = FALSE;
}
csocket::csocket(string& host_name, int port)
{
// Constructor using string host name and port number.
if (!set_active(host_name, port))
{
client_hostname = "";
client_port = 0;
client_init = FALSE;
}
}
csocket::csocket(char *host_name, int port)
{
// Constructor using char host name and port number.
string host;
if (host_name == (char *)NULL || !strlen(host_name))
{
client_hostname = "";
client_port = 0;
client_init = FALSE;
return;
}
host = host_name;
if (!set_active(host, port))
{
client_hostname = "";
client_port = 0;
client_init = FALSE;
}
}
int csocket::set_active(string& host_name, int port_number)
{
/* Set the active server host name and port number.
Method returns 'TRUE' upon success, 'FALSE'
otherwise. */
if (host_name.empty())
return(FALSE);
if (port_number <= 0)
return(FALSE);
/* load class data, do not check connection */
client_hostname = host_name;
client_port = port_number;
client_init = TRUE;
return(TRUE);
}
int csocket::get_active(string& host_name, int& port_number)
{
/* Obtain the current server host name and port number.
Method returns 'TRUE' upon success with the server
host name loaded into 'host_name', the server port number will
be loaded into 'port_number'. Method returns 'FALSE'
upon failure. */
if (host_name.empty())
return(FALSE);
host_name = "";
port_number = 0;
if (!client_init)
return(FALSE);
host_name = client_hostname;
port_number = client_port;
return(TRUE);
}
int csocket::send_receive(string& sbuf, string& rbuf)
{
/* Send a command to the current socket server and
wait for a reply. Method returns 'TRUE' upon
success with the receive contents loaded into
'rbuf'. Method returns 'FALSE' upon failure. */
if (!client_init)
return(FALSE);
if (sbuf.empty())
return(FALSE);
rbuf = "";
/* attempt to connect to currently defined server */
if (!client_connect())
return(FALSE);
/* we are connected, send the command string using
the low level socket send function */
if (send_data(sbuf) == 0)
{
(void)close_socket();
return(FALSE);
}
/* receive reply */
if (recv_data(rbuf) == 0)
{
(void)close_socket();
return(FALSE);
}
(void)close_socket();
return(TRUE);
}
int csocket::send_receive(char *sbuf, string& rbuf)
{
// Send a char array and receive a string.
string sendbuf;
if (sbuf == (char *)NULL || !strlen(sbuf))
return(FALSE);
sendbuf = sbuf;
return(send_receive(sendbuf, rbuf));
}
int csocket::close_socket(void)
{
/* Close the socket between client and server.
Method returns 'TRUE' upon success, 'FALSE'
otherwise. */
#ifdef OS_WIN32
if (closesocket(clientsock) == SOCKET_ERROR)
return(FALSE);
#endif
#ifdef OS_UNIX
close(clientsock);
#endif
return(TRUE);
}
int csocket::recv_data(string& buf)
{
/* Receive data from the socket which is assumed
to be open. Method returns the number of bytes
read upon success with the received data loaded
into 'buf', zero otherwise. */
char *fbuf;
int charRecv, done = FALSE;
fbuf = new char[IPC_SR_BUFSIZE];
buf = "";
while(!done)
{
#ifdef OS_WIN32
charRecv = recv(clientsock, (LPSTR)fbuf, (IPC_SR_BUFSIZE - 1), NO_FLAGS);
#endif
#ifdef OS_UNIX
charRecv = recv(clientsock, fbuf, (IPC_SR_BUFSIZE - 1), NO_FLAGS);
#endif
if (charRecv == SOCKET_ERROR)
{
delete fbuf;
return(0);
}
fbuf[charRecv] = EOS;
buf += fbuf;
if (charRecv < (IPC_SR_BUFSIZE - 1))
done = TRUE;
}
delete fbuf;
return(buf.length());
}
int csocket::send_data(string& buf)
{
/* Send data to the socket. Method returns the
number of bytes sent upon success, zero
otherwise. */
string fbuf;
int len, charSent, pos = 0, bytesToGo, done = FALSE;
int chunk;
len = buf.length();
if (!len)
return(0);
// if less than 'IPC_SR_BUFSIZE' to send, use one shot
if (len < IPC_SR_BUFSIZE)
{
if ((charSent = send(clientsock, buf.c_str(), len, NO_FLAGS)) == SOCKET_ERROR)
return(FALSE);
return(charSent);
}
bytesToGo = len;
// send one buffer length at a time
while(!done)
{
if (bytesToGo > (IPC_SR_BUFSIZE - 1))
chunk = IPC_SR_BUFSIZE - 1;
else
chunk = bytesToGo;
fbuf = buf.substr(pos, chunk);
if ((charSent = send(clientsock, fbuf.c_str(), chunk, NO_FLAGS)) == SOCKET_ERROR)
{
pos = 0;
break;
}
bytesToGo -= chunk;
pos += charSent;
if (bytesToGo <= 0)
done = TRUE;
}
return(pos);
}
int csocket::client_connect(void)
{
/* Use the previously loaded host name and port number to
connect to the server. Method returns 'TRUE' if the
connection was successful, 'FALSE' otherwise. */
if (!client_init)
return(FALSE);
// resolve server host name
lpHostEnt = gethostbyname(client_hostname.c_str());
if (!lpHostEnt)
return(FALSE);
// create the socket
#ifdef OS_WIN32
clientsock = socket(PF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
#endif
#ifdef OS_UNIX
clientsock = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
#endif
if (clientsock == INVALID_SOCKET)
return(FALSE);
// load client address data
memset(&sockClientAddr, 0, sizeof(sockClientAddr));
sockClientAddr.sin_family = AF_INET;
sockClientAddr.sin_port = htons(client_port);
#ifdef OS_WIN32
sockClientAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);
#endif
#ifdef OS_UNIX
sockClientAddr.sin_addr.s_addr = ((struct in_addr *)(lpHostEnt->h_addr))->s_addr;
#endif
// connect to server
#ifdef OS_WIN32
if (connect(clientsock, (LPSOCKADDR)&sockClientAddr, sizeof(sockClientAddr)))
#endif
#ifdef OS_UNIX
if (connect(clientsock, (sockaddr *)&sockClientAddr, sizeof(sockClientAddr)) == SOCKET_ERROR)
#endif
return(FALSE);
return(TRUE);
}