Board index » cppbuilder » TCP TServer- and TClientSocket

TCP TServer- and TClientSocket


2006-11-17 02:58:29 PM
cppbuilder89
Hello
I'm using the TServer- and TClientSocket classes to make en Ethernet connection. I'm using the SendText and ReceiveText metodes, and there is communication. But if I sent e.g 200 packets, as fast as possible, then they are not all received, I have to put in a large delay about 100-150msec between each transmission, if all the packet shall be received, can that be true, or what shall I do?
Best Regards
Kresten Tolstrup
 
 

Re:TCP TServer- and TClientSocket

"Kresten Tolstrup" < XXXX@XXXXX.COM >wrote in message
Quote
I'm using the SendText and ReceiveText metodes
I strongly discourage the use of those methods. You should use SendBuf()
and ReceiveBuf() directly instead.
Quote
if I sent e.g 200 packets, as fast as possible, then they are not all
received
Yes, they are, as TCP guarantees packet delivery. You likely are simply not
reading the packets properly in the first place. Please show your actual
code. Are you taking into account that packets may be split and/or merged
together? I guess would be no.
Quote
I have to put in a large delay about 100-150msec between each transmission
All the more reason to suspect that your reading/writing code is not correct
enough.
Gambit
 

Re:TCP TServer- and TClientSocket

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

"Kresten Tolstrup" < XXXX@XXXXX.COM >wrote in message
news:455d6ba5$ XXXX@XXXXX.COM ...

>I'm using the SendText and ReceiveText metodes

I strongly discourage the use of those methods. You should use SendBuf()
and ReceiveBuf() directly instead.

>if I sent e.g 200 packets, as fast as possible, then they are not all
received

Yes, they are, as TCP guarantees packet delivery. You likely are simply not
reading the packets properly in the first place. Please show your actual
code. Are you taking into account that packets may be split and/or merged
together? I guess would be no.

>I have to put in a large delay about 100-150msec between each transmission

All the more reason to suspect that your reading/writing code is not correct
enough.


Gambit


Hello again
Here is the code, it is in the ClientSocketRead metode. The received message is stored in the queue conStoredRxMsg. When the message is sent the SendText is just called.
string strMail = Socket->ReceiveText().c_str();
if (strMail.size()>0)
{
m_pRxMsgSynchronizer->BeginWrite();
conStoredRxMsg.push(strMail);
m_pRxMsgSynchronizer->EndWrite();
}
Best Regards
Kresten Tolstrup
 

{smallsort}

Re:TCP TServer- and TClientSocket

"Kresten Tolstrup" < XXXX@XXXXX.COM >wrote in message
Quote
Here is the code, it is in the ClientSocketRead metode. The received
message is stored in the queue conStoredRxMsg. When the message
is sent the SendText is just called.
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
make changes to your protocol, then I STRONGLY encourage you to send the
string length along with the string data. That way, the receive can
determine ahead of time exactly how many bytes to read.
Please go to 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.
Gambit
 

Re:TCP TServer- and TClientSocket

Quote
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 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
 

Re:TCP TServer- and TClientSocket

Kresten Tolstrup wrote:
Quote
I have tried to search the newgroup, but without any lock,
groups.google.com/groups/search
First link shows a good method.
Other links also discuss your problems.