Article View: borland.public.cppbuilder.internet.socket
Article #2702Too many calls to OnRead
From: marko.suonpera
Date: Sun, 12 Feb 2006 10:12
Date: Sun, 12 Feb 2006 10:12
310 lines
9192 bytes
9192 bytes
So what's wrong with this code? I create the class Tcpmessager to
handle sending and receiving standard library vectors from another
machine. Either machine could be either server or client.
So when I give std::vector<double> with 15 elements as input to
WriteVector, everything works fine if I have the debugger on in the
receiving machine. If it is not on, I am more likely to get crap.
However, when ReadVector() has finished, OnRead() or OnClientRead()
immediately fire again. If the receiving machine is the server, nothing
gets read here. Then in Application->ProcessMessages() OnRead is called
again and I get a lot of nested calls to ReadVector (7-8 calls
alltogether). If the receiving machine is the server, nothing gets
read, so it is no problem. But if it is the client, sometimes a very
big number, or zero, is read as the vector size (s) on the additional
calls to OnRead and this produces errors.
Then again WriteVector always succeeds (returns true).
So I use the nonblocking mode. When I turned to blocking, the OnRead
events are never called.
I'd like the program to be able to handle vectors of at least 100000
elements long.
//---------------------------------------------------------------------------
#ifndef tcpmessagerH
#define tcpmessagerH
//---------------------------------------------------------------------------
#include <ScktComp.hpp>
#include <vector>
using std::vector;
class Tcpmessager
{
private:
TClientSocket *ClientSocket;
TServerSocket *ServerSocket;
vector<double> v;
public:
Tcpmessager(TComponent* owner);
~Tcpmessager(void);
bool vectorwasread;
AnsiString currenthost;
void FileListen(void);
void FileConnect(AnsiString _host);
void FileDisconnect(void);
bool SendData(TCustomWinSocket *Socket, void *Buffer, int BufSize);
bool ReadData(TCustomWinSocket *Socket, void *Buffer, int BufSize);
bool ReadVector(TCustomWinSocket *Socket);
bool WriteVector(const vector<double> &u);
void GetVector(vector<double> &u) {u = v;}
void __fastcall ServerSocketError(TObject* Sender,
TCustomWinSocket* Socket,
TErrorEvent ErrorEvent, int &ErrorCode);
void __fastcall ClientSocketConnect(TObject* Sender,
TCustomWinSocket* Socket);
void __fastcall ClientSocketRead(TObject* Sender,
TCustomWinSocket* Socket);
void __fastcall ServerSocketClientRead(TObject* Sender,
TCustomWinSocket* Socket);
void __fastcall ServerSocketAccept(TObject* Sender,
TCustomWinSocket* Socket);
void __fastcall ServerSocketClientConnect(TObject* Sender,
TCustomWinSocket* Socket);
void __fastcall ClientSocketDisconnect(TObject* Sender,
TCustomWinSocket* Socket);
void __fastcall ClientSocketError(TObject* Sender,
TCustomWinSocket* Socket, TErrorEvent ErrorEvent
, int &ErrorCode);
void __fastcall ServerSocketClientDisconnect(TObject* Sender,
TCustomWinSocket* Socket);
};
#endif
tcpmessager.cpp:
#include "tcpmessager.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
Tcpmessager::Tcpmessager(TComponent* owner)
{
ClientSocket = new TClientSocket(owner);
ServerSocket = new TServerSocket(owner);
ServerSocket->OnAccept = &ServerSocketAccept;
ServerSocket->OnClientConnect = &ServerSocketClientConnect;
ServerSocket->OnClientDisconnect = &ServerSocketClientDisconnect;
ServerSocket->OnClientRead = &ServerSocketClientRead;
ServerSocket->OnClientError = &ServerSocketError;
ClientSocket->OnConnect = &ClientSocketConnect;
ClientSocket->OnDisconnect = &ClientSocketDisconnect;
ClientSocket->OnError = &ClientSocketError;
ClientSocket->OnRead = &ClientSocketRead;
ServerSocket->ServerType = stNonBlocking;
ServerSocket->Port = 1024;
ClientSocket->ClientType = ctNonBlocking;
ClientSocket->Port = 1024;
vectorwasread = false;
currenthost = "";
}
Tcpmessager::~Tcpmessager(void)
{
ServerSocket->Close();
ClientSocket->Close();
delete ServerSocket;
delete ClientSocket;
}
void Tcpmessager::FileListen(void)
{
ClientSocket->Close();
ServerSocket->Open();
}
void Tcpmessager::FileConnect(AnsiString _host)
{
if (ClientSocket->Active) ClientSocket->Active = false;
if (_host.Length() > 0){
ClientSocket->Host = _host;
ClientSocket->Open();
}
}
void Tcpmessager::FileDisconnect(void)
{
ClientSocket->Close();
ServerSocket->Close();
}
bool Tcpmessager::SendData(TCustomWinSocket *Socket, void *Buffer, int
BufSize)
{
LPBYTE pBuf = (LPBYTE) Buffer;
while( BufSize > 0 )
{
int sent = Socket->SendBuf(pBuf, BufSize);
if( sent < 0 )
{
if( WSAGetLastError() != WSAEWOULDBLOCK ) return false;
Application->ProcessMessages();
continue;
}
if( sent == 0 ) // socket disconnected
{
return false;
}
pBuf += sent;
BufSize -= sent;
}
return true;
}
bool Tcpmessager::ReadData(TCustomWinSocket *Socket, void *Buffer, int
BufSize)
{
LPBYTE pBuf = (LPBYTE) Buffer;
while( BufSize > 0 )
{
int read = Socket->ReceiveBuf(pBuf, BufSize);
if( read < 0 )
{
if( WSAGetLastError() != WSAEWOULDBLOCK ) return false;
Application->ProcessMessages();
continue;
}
if( read == 0 ){
// socket disconnected
return false;
}
pBuf += read;
BufSize -= read;
}
return true;
}
bool Tcpmessager::ReadVector(TCustomWinSocket *Socket)
{
int s = 0;
if( ReadData(Socket, &s, sizeof(int)) && s > 0)
{
v.resize(s);
for(int i = 0; i < s; i++)
{
if(!ReadData(Socket, &(v[i]), sizeof(double)) )
return false;
}
}
else return false;
return true;
}
bool Tcpmessager::WriteVector(const vector<double> &u)
{
TCustomWinSocket *Socket;
int n = u.size();
double temp;
if (ClientSocket->Active) Socket = ClientSocket->Socket;
else if (ServerSocket->Socket->ActiveConnections > 0)
Socket = ServerSocket->Socket->Connections[0];
else return false;
if( SendData(Socket, &(n), sizeof(int)) )
{
for(int i = 0; i < n; i++)
{
temp = u[i];
if( !SendData(Socket, &temp, sizeof(double)) )
return false;
}
}
else return false;
return true;
}
void __fastcall Tcpmessager::ClientSocketConnect(TObject* Sender,
TCustomWinSocket* Socket)
{
currenthost = Socket->RemoteHost;
}
void __fastcall Tcpmessager::ClientSocketRead(TObject* Sender,
TCustomWinSocket* Socket)
{
ReadVector(Socket);
vectorwasread = true;
}
void __fastcall Tcpmessager::ServerSocketClientRead(TObject* Sender,
TCustomWinSocket* Socket)
{
ReadVector(Socket);
vectorwasread = true;
}
void __fastcall Tcpmessager::ServerSocketAccept(TObject*
Sender, TCustomWinSocket* Socket)
{
//nothing
}
void __fastcall Tcpmessager::ServerSocketClientConnect(TObject* Sender,
TCustomWinSocket* Socket)
{
currenthost = Socket->RemoteHost;
}
void __fastcall Tcpmessager::ServerSocketClientDisconnect(TObject*
Sender, TCustomWinSocket* Socket)
{
ServerSocket->Close();
ServerSocket->Open();
currenthost = "";
}
void __fastcall Tcpmessager::ClientSocketDisconnect(TObject* Sender,
TCustomWinSocket* Socket)
{
currenthost = "";
}
void __fastcall Tcpmessager::ClientSocketError(TObject* Sender,
TCustomWinSocket* Socket, TErrorEvent ErrorEvent
, int &ErrorCode)
{
//show error msg
ErrorCode = 0;
}
void __fastcall Tcpmessager::ServerSocketError(TObject* Sender,
TCustomWinSocket* Socket,
TErrorEvent ErrorEvent, int &ErrorCode)
{
//show error msg
ErrorCode = 0;
}
Technical Details
Message-ID:
<1139739145.875731.77940@g44g2000cwa.googlegroups.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!postnews.google.com!g44g2000cwa.googlegroups.com!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Thread: 11508e,45664700a055b46a,start X-Google-Attributes: gid11508e,public X-Google-Language: ENGLISH,ASCII-7-bit Path: arc1-ca.pugleaf.net!g2news1.google.com!postnews.google.com!g44g2000cwa.googlegroups.com!not-for-mail From: marko.suonpera@24net.zzn.com Newsgroups: borland.public.cppbuilder.internet.socket Subject: Too many calls to OnRead Date: 12 Feb 2006 02:12:25 -0800 Organization: http://groups.google.com Lines: 311 Message-ID: <1139739145.875731.77940@g44g2000cwa.googlegroups.com> NNTP-Posting-Host: 130.188.8.10 Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Trace: posting.google.com 1139739150 12545 127.0.0.1 (12 Feb 2006 10:12:30 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Sun, 12 Feb 2006 10:12:30 +0000 (UTC) User-Agent: G2/0.2 X-HTTP-UserAgent: Opera/7.54u1 (Windows NT 5.1; U) [en],gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: g44g2000cwa.googlegroups.com; posting-host=130.188.8.10; posting-account=UpYnTw0AAADMPWcPv43CBbekFgE2xLoE