🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internet.socket
Article #1686

Re: TCP TServer- and TClientSocket

#1686
From: Kresten Tolstrup
Date: Sun, 19 Nov 2006 10:46
230 lines
8703 bytes
>Please show ALL of the reading/writing code.  Again, I STRONGLY discourage
>the use of SendText() and ReceiveText().  Also, if you are at liberty to
>Please go to http://www.deja.com and search through the newsgroup archives.
>This topic has been discussed in detail MANY MANY times before, with full
>code samples provided.

I have tried to search the newgroup, but without any lock, could you maybe give me a new link. I have changed the Send- and ReceiveText to Send- and ReceiveBuf, but with the same result. Here is the hole code for the server part, the client is build in the same way.

The TdpIP is a class, just keeping address, hostname and portnumber.

//---------------------------------------------------------------------------

#pragma hdrstop

#include <assert.h>

#include "dpRadioTCPServer.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"


const int ciNoIndexFound = 10000;
using namespace std;

//---------------------------------------------------------------------------
__fastcall TfmRadioTCPServer::TfmRadioTCPServer(int iIPPortNo, TComponent* Owner)
   : TForm(Owner), m_ulLastSendTime(0)
{
   m_pClientSynchronizer = new TMultiReadExclusiveWriteSynchronizer;
   m_pRxMsgSynchronizer = new TMultiReadExclusiveWriteSynchronizer;
   m_IPSynchronizer = new TMultiReadExclusiveWriteSynchronizer;
   m_clIP.strHost = "";
   m_clIP.strIPAddr = "";
   m_clIP.iIPPortNo = iIPPortNo;
   ServerSocket->Port = iIPPortNo;
   ServerSocket->Open();
}
//---------------------------------------------------------------------------
__fastcall TfmRadioTCPServer::~TfmRadioTCPServer()
{
   ServerSocket->Close();
   delete m_pClientSynchronizer;
   delete m_pRxMsgSynchronizer;
   delete m_IPSynchronizer;
   delete ServerSocket;
}
//---------------------------------------------------------------------------
//A client is connected to the server
void __fastcall TfmRadioTCPServer::ServerSocketClientConnect(
      TObject *Sender, TCustomWinSocket *Socket)
{
   TdpIP clClient(Socket->RemoteAddress.c_str(), Socket->RemotePort);
   clClient.strHost = Socket->RemoteHost.c_str();
   m_pClientSynchronizer->BeginWrite();
   m_conClientConnected.push_back(clClient);
   m_pClientSynchronizer->EndWrite();
   m_IPSynchronizer->BeginWrite();
   m_clIP.strHost = Socket->LocalHost.c_str();
   m_clIP.strIPAddr = Socket->LocalAddress.c_str();
   m_clIP.iIPPortNo = Socket->LocalPort;
   m_IPSynchronizer->EndWrite();
}
//---------------------------------------------------------------------------
TdpIP TfmRadioTCPServer::GetThisIP()
{
   TdpIP clIP;
   m_IPSynchronizer->BeginRead();
   clIP =  m_clIP;
   m_IPSynchronizer->EndRead();
   return clIP;
}
//---------------------------------------------------------------------------
bool TfmRadioTCPServer::GetConnected(tconClientConnected& conClientConnected)
{
    bool bReturn = false;
    m_pClientSynchronizer->BeginRead();
    if (m_conClientConnected.size() > 0)
    {
      conClientConnected = m_conClientConnected;
      bReturn = true;
    }
    m_pClientSynchronizer->EndRead();
    return bReturn;
}
//---------------------------------------------------------------------------
//A message sent from the client, is received here
void __fastcall TfmRadioTCPServer::ServerSocketClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
    char *pcData = NULL;
    try
    {
      int iByte = Socket->ReceiveLength();
      pcData = new char[iByte];
      if (iByte > 0)
      {
         iByte = Socket->ReceiveBuf(pcData, iByte);
         string strMsg(pcData, iByte);
         if (strMsg.size() > 0)
         {
            m_pRxMsgSynchronizer->BeginWrite();
            m_conStoredRxMsg.push(strMsg);
            m_pRxMsgSynchronizer->EndWrite();
         }
      }
    }
    catch(...)
    {
       assert(0);
    }
    if (pcData != NULL)
    {
      delete pcData;
    }
}
//------------------------------------------------------------------------------
bool TfmRadioTCPServer::GetMail(std::string &strMail)
{
   bool bReturn = false;
   m_pRxMsgSynchronizer->BeginWrite();
   if (m_conStoredRxMsg.size() > 0)
   {
      strMail = m_conStoredRxMsg.front();
      m_conStoredRxMsg.pop();
      bReturn = true;
   }
   m_pRxMsgSynchronizer->EndWrite();
   return bReturn;
}
//---------------------------------------------------------------------------
void __fastcall TfmRadioTCPServer::ServerSocketClientDisconnect(
      TObject *Sender, TCustomWinSocket *Socket)
{
     DisConnectSocket(Socket);
}
//---------------------------------------------------------------------------
void __fastcall TfmRadioTCPServer::ServerSocketClientError(
      TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent,
      int &ErrorCode)
{
     ErrorCode = 0;
     DisConnectSocket(Socket);
}
//---------------------------------------------------------------------------
void __fastcall TfmRadioTCPServer::DisConnectSocket(TCustomWinSocket *Socket)
{
     TdpIP Client(Socket->RemoteAddress.c_str(), Socket->RemotePort);
     TdpIP ReadClient;

     m_pClientSynchronizer->BeginWrite();
     std::vector<TdpIP>::iterator itClient;
     for (itClient = m_conClientConnected.begin(); itClient != m_conClientConnected.end(); itClient++)
     {
        ReadClient = (*itClient);
        if (Client.strIPAddr == ReadClient.strIPAddr && Client.iIPPortNo == ReadClient.iIPPortNo)
        {
            m_conClientConnected.erase(itClient);
            break;
        }
     }
     m_pClientSynchronizer->EndWrite();
}
//---------------------------------------------------------------------------
int TfmRadioTCPServer::SendMail(TdpIP clRX, std::string strTxMsg)
{
    unsigned long ulMinTimeBetweenTx = 100;
    int iByte=0;
    try
    {
       int iIndex = GetConnectIndex(&clRX);
       if (iIndex != ciNoIndexFound)
       {
          unsigned long ulDiffTime = GetTickCount() - m_ulLastSendTime;
          if (ulDiffTime < ulMinTimeBetweenTx)
          {
            Sleep(ulMinTimeBetweenTx - ulDiffTime);
          }
          for (int i=0; i<3; i++)
          {
             char *pcData;
             pcData = new char[strTxMsg.size()];
             strTxMsg.copy(pcData, strTxMsg.size());
             iByte = ServerSocket->Socket->Connections[iIndex]->SendBuf(pcData, strTxMsg.size());
             m_ulLastSendTime = GetTickCount();
             if (iByte != 0)
             {
                break;
             }
             Sleep(200);
          }
          if (iByte == 0)
          {
             assert(0);
          }
       }
    }
    catch(...)
    {
      assert(0);
    }
    return iByte;
}
//---------------------------------------------------------------------------
int TfmRadioTCPServer::GetConnectIndex(TdpIP *pclIP)
{
   int iReturn = ciNoIndexFound;
   for (int iIndex=0; iIndex<ServerSocket->Socket->ActiveConnections; iIndex++)
   {
      if ((ServerSocket->Socket->Connections[iIndex]->RemoteAddress == pclIP->strIPAddr.c_str()) ||
          (ServerSocket->Socket->Connections[iIndex]->RemoteHost == pclIP->strHost.c_str()))
      {
         iReturn=iIndex;
         break;
      }
   }
   return iReturn;
}
//------------------------------------------------------------------------------
void __fastcall TfmRadioTCPServer::ServerSocketAccept(TObject *Sender,
      TCustomWinSocket *Socket)
{
   //
}
//------------------------------------------------------------------------------
 
Best Regards
Kresten Tolstrup
Technical Details
Message-ID: <45604402$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <455d6ba5$1@newsgroups.borland.com> <455d71f5$1@newsgroups.borland.com> <455e2228$1@newsgroups.borland.com> <455e2e94@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,a552fcaaf39b63f9
X-Google-Attributes: gid11508e,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Kresten Tolstrup" <kt@danphone.com>
Sender: "Kresten Tolstrup" <kt@danphone.com>
Reply-To: "Kresten Tolstrup" <kt@danphone.com>
Subject: Re: TCP TServer- and TClientSocket
Newsgroups: borland.public.cppbuilder.internet.socket
X-User-Info: 80.162.206.172     
References: <455d6ba5$1@newsgroups.borland.com> <455d71f5$1@newsgroups.borland.com> <455e2228$1@newsgroups.borland.com> <455e2e94@newsgroups.borland.com>
NNTP-Posting-Host: 207.105.83.66
Message-ID: <45604402$1@newsgroups.borland.com>
Date: 19 Nov 2006 03:46:10 -0700
X-Trace: newsgroups.borland.com 1163936770 207.105.83.66 (19 Nov 2006 03:46:10 -0700)
Lines: 232
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail