Die_Backe
12.03.2006, 20:07
Hallo,
Um ein grafisches Programm von mir besser debuggen zu können, hab ich ein Debugger-Tool geschrieben, dem das grafische Programm über einen Socket Text schicken kann, den der Debugger dann auf der Konsole ausgibt. Dazu verwende ich eine selbst geschriebene Socket-Klasse und eine ebenfalls selbst geschriebene Debugger-Klasse. Der Debugger horcht dauerhaft auf dem Debug-Port, und connected beim Programmstart auf dem Servercheck-port (beide ports in einem header definiert). Das Programm seinerseits baut beim Starten eine Verbindung auf dem Debug-port auf, und horcht auf dem servercheck-port, falls der Debugger nachträglich startet. Die Klasse "Debugger" spielt dabei die Rolle, dass sie auf der Programmseite die Verbindung aufbaut und hält.
Das Problem ist jetzt folgendes: Wenn ich mehrere Nachrichten gleichzeitig versende, also im Stil
gDebugger<<"PLONK1\n"<<"PLONK2\n"<<"PLONK3\n"<<"PLONK4\n;
, dann kommt auf jeden Fall das erste Plonk an, aber von den anderen Plonks fehlen die meisten. Die Reihenfolge der Pakete stimmt, aber, dass wirklich alle ankommen passiert so gut wie nie. Wenn ich breakpoints setze, um zu gucken wo das Paket stecken bleibt, geht plötzlich alles... der Fehler tritt nur auf wenn die Pakete nichtnur im Code, sondern auch praktisch gleichzeitig versandt werden.
Ich verwende GCC auf meinem Windows XP (Dev-Cpp als IDE).
Soviel zum Problem, jetzt kommt nurnoch verwendeter Code (gekürzt natürlich, für das Wohl der Forennutzer. Tut mir leid, weiter kann ich das Problem nicht eingrenzen):
Aus der Socket-Klasse:
(mHandle ist der sockethandle des jeweiligen sockets)
Socket::Socket()
{
Socket::init();
if ((mHandle = ::socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
return; //unhandled error
};
mIsConnected = false; //wird bei connect() auf true gesetzt.
};
Socket::~Socket()
{
closesocket(mHandle);
};
Socket& Socket::operator<<(const char* msg)
{
this->send(msg);
return *this;
};
int Socket::send(const char *msg, int flags = 0)
{
this->send(msg, strlen(msg) + 1, flags);
};
int Socket::send(const char *msg, size_t len, int flags = 0)
{
if (::send(mHandle, msg, len, flags) == -1)
{
return -1;
};
};
int Socket::recv(char *buffer, size_t len, struct timeval* timeout = NULL, int flags = 0)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(mHandle, &fds);
::select(mHandle + 1, &fds, NULL, NULL, timeout);
if (FD_ISSET(mHandle, &fds))
{
int bytes;
if ((bytes = ::recv(mHandle, buffer, len, flags)) == -1)
{
return -1;
};
return bytes;
};
return 0;
};
und der Debugger (also die Klasse, die auf der Programm-Seite die Daten Sendet)
void Debugger::send(const char* msg)
{
//If the Debugger Program was not found yet
if (!this->IsConnected()) //guckt ob der Debug.Socket connected ist
{
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
//look whether it has started
Socket* s = mServer.accept(&timeout);
if (NULL != s)
{
//if Debugger-Program has started, connect to it
delete s;
/* mClient ist das Socket-Objekt, das auf dem Debug-Port sendet. */
mClient.connect("127.0.0.1", PORT_DEBUG);
}
else
{
return; //unhandled error, accept() failed.
};
};
//send the messange
mClient<<(msg);
};
Und das Debuggerprogramm sieht im Kern so aus:
for(;;)
{
Socket *sock = serversocket.accept();
if (sock == NULL)
{
perror("accept() failed");
system("pause");
continue;
};
cout<<"Client is connecting..."<<endl;
char buffer[BUFFER_SIZE];
int bytes;
while((bytes = sock->recv(buffer, sizeof(buffer))) > 0)
{
cout<<buffer;
buffer[0] = 0;
};
delete sock;
sock = NULL;
cout<<"Connection Closed."<<endl;
};
Edit: Hab nicht mitgedacht und ins falsche Forum gepostet... Das Wort in den Eckigen Klammern sollte jetzt vllt lieber C++ und nicht Sockets heißen...
Um ein grafisches Programm von mir besser debuggen zu können, hab ich ein Debugger-Tool geschrieben, dem das grafische Programm über einen Socket Text schicken kann, den der Debugger dann auf der Konsole ausgibt. Dazu verwende ich eine selbst geschriebene Socket-Klasse und eine ebenfalls selbst geschriebene Debugger-Klasse. Der Debugger horcht dauerhaft auf dem Debug-Port, und connected beim Programmstart auf dem Servercheck-port (beide ports in einem header definiert). Das Programm seinerseits baut beim Starten eine Verbindung auf dem Debug-port auf, und horcht auf dem servercheck-port, falls der Debugger nachträglich startet. Die Klasse "Debugger" spielt dabei die Rolle, dass sie auf der Programmseite die Verbindung aufbaut und hält.
Das Problem ist jetzt folgendes: Wenn ich mehrere Nachrichten gleichzeitig versende, also im Stil
gDebugger<<"PLONK1\n"<<"PLONK2\n"<<"PLONK3\n"<<"PLONK4\n;
, dann kommt auf jeden Fall das erste Plonk an, aber von den anderen Plonks fehlen die meisten. Die Reihenfolge der Pakete stimmt, aber, dass wirklich alle ankommen passiert so gut wie nie. Wenn ich breakpoints setze, um zu gucken wo das Paket stecken bleibt, geht plötzlich alles... der Fehler tritt nur auf wenn die Pakete nichtnur im Code, sondern auch praktisch gleichzeitig versandt werden.
Ich verwende GCC auf meinem Windows XP (Dev-Cpp als IDE).
Soviel zum Problem, jetzt kommt nurnoch verwendeter Code (gekürzt natürlich, für das Wohl der Forennutzer. Tut mir leid, weiter kann ich das Problem nicht eingrenzen):
Aus der Socket-Klasse:
(mHandle ist der sockethandle des jeweiligen sockets)
Socket::Socket()
{
Socket::init();
if ((mHandle = ::socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
return; //unhandled error
};
mIsConnected = false; //wird bei connect() auf true gesetzt.
};
Socket::~Socket()
{
closesocket(mHandle);
};
Socket& Socket::operator<<(const char* msg)
{
this->send(msg);
return *this;
};
int Socket::send(const char *msg, int flags = 0)
{
this->send(msg, strlen(msg) + 1, flags);
};
int Socket::send(const char *msg, size_t len, int flags = 0)
{
if (::send(mHandle, msg, len, flags) == -1)
{
return -1;
};
};
int Socket::recv(char *buffer, size_t len, struct timeval* timeout = NULL, int flags = 0)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(mHandle, &fds);
::select(mHandle + 1, &fds, NULL, NULL, timeout);
if (FD_ISSET(mHandle, &fds))
{
int bytes;
if ((bytes = ::recv(mHandle, buffer, len, flags)) == -1)
{
return -1;
};
return bytes;
};
return 0;
};
und der Debugger (also die Klasse, die auf der Programm-Seite die Daten Sendet)
void Debugger::send(const char* msg)
{
//If the Debugger Program was not found yet
if (!this->IsConnected()) //guckt ob der Debug.Socket connected ist
{
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
//look whether it has started
Socket* s = mServer.accept(&timeout);
if (NULL != s)
{
//if Debugger-Program has started, connect to it
delete s;
/* mClient ist das Socket-Objekt, das auf dem Debug-Port sendet. */
mClient.connect("127.0.0.1", PORT_DEBUG);
}
else
{
return; //unhandled error, accept() failed.
};
};
//send the messange
mClient<<(msg);
};
Und das Debuggerprogramm sieht im Kern so aus:
for(;;)
{
Socket *sock = serversocket.accept();
if (sock == NULL)
{
perror("accept() failed");
system("pause");
continue;
};
cout<<"Client is connecting..."<<endl;
char buffer[BUFFER_SIZE];
int bytes;
while((bytes = sock->recv(buffer, sizeof(buffer))) > 0)
{
cout<<buffer;
buffer[0] = 0;
};
delete sock;
sock = NULL;
cout<<"Connection Closed."<<endl;
};
Edit: Hab nicht mitgedacht und ins falsche Forum gepostet... Das Wort in den Eckigen Klammern sollte jetzt vllt lieber C++ und nicht Sockets heißen...