Knowledge Base Nr: 00163 spsclient.cpp - http://www.swe-kaiser.de

Downloads:

linux: client für socket-schnittstelle (für forms zu spsserver)

  
//////////////////////// c interface

int SPSConnect(const char* lpszIP, int nPort);
int SPSDisconnect();
int SPSDoCmd(const char* lpszCmd, char* szAnswer, int nMaxLen, int nTimeout);
int SPSGetValue(const char* lpszAddr, char* szValue, int nTimeout); //z.b.: 'SPS1 R100.33' -> ''

//////////////////////// cpp interface

class CSPSClient
{
public:
CSPSClient();
~CSPSClient();

int Connect(const char* lpszIP, int nPort);
int Disconnect();

int DoCmd(const char* lpszCmd, char* szAnswer, int nMaxLen, int nTimeout);
int GetValue(const char* lpszAddr, char* szValue, int nTimeout);

protected:
int m_sockfd;
};

//////////////////////// cpp sample

int nErr = 0;

CSPSClient sps;

nErr = sps.Connect(SPSIP, PORT);
TRACE("Connect(%s, %d): err:%d", SPSIP, PORT, nErr);

const char* lpszCmd = "get 33 SPS1 m10";
const char* lpszGet = "SPS1 r100.33";
char szAnswer[200] = {0};

nErr = sps.DoCmd(lpszCmd, szAnswer, sizeof(szAnswer), TIMEOUT);
TRACE("DoCmd(%s, <%s>, %d, %d): err:%d", lpszCmd, szAnswer, sizeof(szAnswer), TIMEOUT, nErr);

nErr = sps.GetValue(lpszGet, szAnswer, TIMEOUT);
TRACE("GetValue(%s, <%s>, %d, %d): err:%d", lpszGet, szAnswer, sizeof(szAnswer), TIMEOUT, nErr);

nErr = sps.Disconnect();
TRACE("Disconnect(): err:%d", nErr);

//////////////////////// forms sample

--read
declare
ec NUMBER;
szValue VARCHAR2(100) := '';
nSize NUMBER := 100;
nTimeout NUMBER := 1000; --in ms
begin
ec := SPSClient.SPSConnect(:MAINBLOCK.IPADDRSERVER, :MAINBLOCK.PORTNO);
ec := SPSClient.SPSDoCmd(:MAINBLOCK.CMD, szValue, nSize, nTimeout);
:MAINBLOCK.ERR := ec;
:MAINBLOCK.ANSWER := szValue;
synchronize;
end;

//////////////////////// cpp implementation

int CSPSClient::Connect(const char* lpszIP, int nPort)
{
struct hostent* rechner;

rechner = gethostbyname(lpszIP);
if (rechner == 0)
{
TRACE("ERROR: gethostbyname(): errno: %d strerror: %s", errno, strerror(errno));
return -1;
}

struct sockaddr_in adresse;
adresse.sin_family = AF_INET;
adresse.sin_port = htons(nPort);
memcpy(&adresse.sin_addr, rechner->h_addr_list[0], sizeof(adresse.sin_addr));

m_sockfd = socket(PF_INET, SOCK_STREAM, 0);
if (m_sockfd<0)
{
TRACE("ERROR: socket(). errno: %d strerror: %s", errno, strerror(errno));
return -2;
}

int nErr = 0;

nErr = connect(m_sockfd, (struct sockaddr*)&adresse, sizeof(adresse));
if (nErr != 0)
{
TRACE("ERROR: connect(%s, %d). errno: %d strerror: %s", lpszIP, nPort, errno, strerror(errno));
return -3;
}

//banner überlesen
char szCmd[MAXBUFFER];
read(m_sockfd, szCmd, sizeof(szCmd));

return 0;
}

int CSPSClient::Disconnect()
{
if (m_sockfd)
{
close(m_sockfd);
m_sockfd = 0;
}
return 0;
}

int CSPSClient::DoCmd(const char* lpszCmd, char* szAnswer, int nMaxLen, int nTimeout)
{
szAnswer[0] = 0;

char szCmd[MAXBUFFER];

sprintf(szCmd, "%s\r\n", lpszCmd);

int nCmdLen = strlen(szCmd);
int nErr = write(m_sockfd, szCmd, nCmdLen);
if (nErr != nCmdLen)
{
TRACE("ERROR: write(). errno: %d strerror: %s", errno, strerror(errno));
return -4;
}

for (int n=0; n<nTimeout; n++)
{
int nLen = read(m_sockfd, szCmd, sizeof(szCmd));
if (nLen < 0)
{
TRACE("ERROR: read(): errno: %d strerror: %s", errno, strerror(errno));
return -4;
}
else if (nLen > nMaxLen)
{
TRACE("ERROR: read(): ext. Puffer zu klein!");
return -5;
}
else if (nLen > 0) //ok
{
szCmd[nLen] = 0;
char* p1 = strchr(szCmd, '\r'); //cr/lf abschneiden
if (p1)
*p1 = 0;

char* p2 = strchr(szCmd, '\n'); //cr/lf abschneiden
if (p2)
*p2 = 0;

strcpy(szAnswer, szCmd);

TRACE("RECV: (%d bytes) <%s>", nLen, szCmd);
break;
}

usleep(1*1000);
}

return 0;
}