Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
19.03.2003, 21:36
snoopdog



Hi,
bin grad dabei mir Winsock in ne Klasse zu packen, so das ich es bequem immer wieder einsetzen kann. ja schön und gut, die send und recv funktion klappt bei meinem IRC Bot super. D.h. ich sende dem Server etwas und empfange auch etwas. Nur wo ich jetzt ne nServer und nen Client dazu gebastelt habe, empfängt der server nix, oder es kan nauhc sein, das der Client nix sendet. Also verbinden tun sich die beiden und sie beenden sich sich auch nicht.
hier mal der teil vom code vom server
Quellcode:#include "socketclass.h"

#include <stdio.h>
#include <windows.h>

char *recvText;
long rc1;

int main()
{
    SocketClass *sc;

    sc = new SocketClass;

    recvText = new char[1024];

    sc->StartWinsock();    //Winsock starten

    sc->SocketStartup(1);  //Socket initiallisieren

    sc->SocketStartServer(200,1);   //Server starten


    while(rc1!=SOCKET_ERROR)
    {
        recvText = sc->SocketRecv(0);
        printf("%s",recvText);
        
    }

    
    


    return 0;
}
und nun vom Client
Quellcode:#include "socketclass.h"

#include <stdio.h>
#include <windows.h>

long rc1;
char text[200];


int main()
{
    SocketClass *sc;

    sc = new SocketClass;

    sc->StartWinsock();       //Winsock starten

    sc->SocketStartup(1);     //Socket initiallisieren

    sc->SocketConnect("127.0.0.1",200);      //verbinden

    while(rc1!=SOCKET_ERROR)
    {
        gets(text);

        rc1 = sc->SocketSend(text,0);
        if(rc1!=SOCKET_ERROR)
        {
            printf("%s",text);
        }
    }



    return 0;
}
wie gesagt ,die send und recv funktionen klappen bei meinem IRC Bot...

--

Visit our 500er Gamer Lan
@ www.evil-lanparty.de or
@ www.evil-havoc.com
Visit the HaVoc Lanparty Community
@ www.havoc-lanparty.com

zum Seitenanfang zum Seitenende Profil || Suche
001
20.03.2003, 10:06
the_viking



kann es sein, das sc->SocketSend(void* data,int lenght) oder so ist? wenn das so ist und du "0" für die Länge der Daten angibst, sendet der auch nichts.
sc->SocketSend(text,strlen(text));
wäre besser dann

--

thx, cu, MfG the_viking

(( My =]=H=O=M=E=> Page! ))
Coder bei Brainshock-Interactive und bei Z-Software
My ICQ: #160959446

zum Seitenanfang zum Seitenende Profil || Suche
002
20.03.2003, 15:22
Prefect



Das Design deiner Socket-Klasse wirkt gar nicht gut.

Quellcode:sc = new SocketClass;

    recvText = new char[1024];

    sc->StartWinsock();    //Winsock starten

    sc->SocketStartup(1);  //Socket initiallisieren

    sc->SocketStartServer(200,1);   //Server starten
Warum all die Verkapselung, wenn du die Aufgabe damit letztendlich doch nicht leichter machst?

Wie wäre es mit einem System, bei dem du einfach folgendes machst:

Quellcode:sc = new Socket;
sc->Listen(); // Server starten
Kann es sein, dass du nur listen() aufrufst und nicht accept()? Ohne accept() geht bei Streamsockets nämlich gar nichts.

Dann:

Quellcode:recvText = new char[1024];

   ....

        recvText = sc->SocketRecv(0);
WAS ist das? Du reservierst zuerst Speicher für die zu empfangenden Daten, aber a) sagst du SocketRecv() nicht, dass es diesen Speicher verwenden sollst und b) überschreibst du den Pointer durch den Aufruf von SocketRecv(). Das macht einfach keinen Sinn.
Ferner fehlen jegliche deletes in deinem Code, d.h. du wirst sehr schnell sehr viele Memory Leaks haben.

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
003
10.04.2003, 14:39
snoopdog



Quellcode:#include "socketclass.h"
#include <stdio.h>

long rc;
char buffer[1024];

int SocketClass::StartWinsock()
{
    WSADATA wsa;
    
    return WSAStartup(MAKEWORD(2,0),&wsa);

}

int SocketClass::SocketStartup(int TCP)
{
    if(TCP==1)
    {
        s = socket(AF_INET,SOCK_STREAM,0);
        if(s==INVALID_SOCKET)
        {
        
            return 0;
        }
        else
        {
        
            return 1;
        }
        
    }
    else
    {
        s = socket(AF_INET,SOCK_DGRAM,0);
        if(s==INVALID_SOCKET)
        {
        
            return 0;
        }
        else
        {
        
            return 1;
        }
    }

}

int SocketClass::SocketConnect(char *IP,int Port)
{
    
    memset(&addr,0,sizeof(SOCKADDR_IN));

    addr.sin_addr.s_addr = inet_addr(IP);

    addr.sin_family = AF_INET;

    addr.sin_port = htons(Port);


    rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
    if(rc==SOCKET_ERROR)
    {
        return 0;
    }
    else
    {
        
        return 1;
    }



}

int SocketClass::SocketSend(char *sendstr,int flags)
{
    rc = send(s,sendstr,strlen(sendstr),flags);

    return rc;
}

char *SocketClass::SocketRecv(int flags)
{

    rc = recv(s,buffer,sizeof(buffer),flags);

    buffer[rc] = '\0';

    printf("%s",buffer);

    return buffer;
}

int SocketClass::SocketStartServer(int Port,int connections)
{
    memset(&addr,0,sizeof(SOCKADDR_IN));
    
    addr.sin_family=AF_INET;

    addr.sin_port=htons(Port);

    addr.sin_addr.s_addr= 0;

    rc = bind(s,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
    
    if(rc==SOCKET_ERROR)
    {
        printf("Fehler beim aufbauen des Ports\n");
        return 0;
    }
    else
    {
        printf("Erfolgreich mit Port:  %d  :verbunden\n",Port);
        
    }

    rc=listen(s,connections);

    if(rc==SOCKET_ERROR)

    {

         printf("Fehler: listen, fehler code: %d\n",WSAGetLastError());


         return 0;

    }
        
    else

    {

        printf("acceptSocket ist im listen Modus....\n");
        

    }

    connectedsocket=accept(s,NULL,NULL);

    if(connectedsocket==INVALID_SOCKET)

    {

        printf("Fehler: accept, fehler code: %d\n",WSAGetLastError());

        return 0;

    }

    else

    {

        printf("Neue Verbindung wurde akzeptiert!\n");

    }


}
hier ist mal die komplette socketclass.cpp

@Prefect: Wie meinst du solle ich es denn sonst machen(Dem Pointer und dem Speicher bei der Recv Funktion)? Naja und die accept funktion rufe ich schon auf.

Und warum ich das so kompliziert mache, ka mir ist was anderes am Anfang nicht eingefallen *g*

PS: bei meinem IRC Bot funktioniert die send und recv Funktion einwandfrei nur warum hier nicht??

--

Visit our 500er Gamer Lan
@ www.evil-lanparty.de or
@ www.evil-havoc.com
Visit the HaVoc Lanparty Community
@ www.havoc-lanparty.com

zum Seitenanfang zum Seitenende Profil || Suche
004
12.04.2003, 15:08
Prefect



Ich bleibe bei meiner Einschätzung: Wenn du die Verkapselung nicht nutzt um dir das Leben einfacher zu machen (weniger, aber dafür ausdruckskräftigere Methoden), dann ist die Verkapselung nichts wert und du kannst es gleich bleiben lassen.

Wieso baust du deine NIHRecv()-Funktion nicht einfach so auf, wie die recv()-Funktion selbst, das wäre doch am logischsten? D.h. du übergibst ihr einen Pointer auf den Puffer sowie die Länge des Puffers, und sie gibt die Anzahl der empfangenen Bytes zurück.

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
005
12.04.2003, 19:37
TheTinySteini



Sorry for Hijacking, aber sag mal Prefect, wie machst du das eigentlich mit Initialisierungen beim Konstruktor? Nehmen wir dein Socket-"Beispiel", sc = new Socket. Jetzt wär's ja z.B. zu überlegen, den WSAStartup-Call direkt im Konstruktor aufzurufen, weil er sowieso gebraucht wird, ganz egal ob nachher ein listen oder ein connect kommt. Kann aber natürlich sein, dass das WSA subsystem mit nem Fehler abbricht. Was dann? Im Konstruktor is ja mit Rückgabewerten schlecht. Ein sc->Init() nur für so nen Krams ist aber auch irgendwo blöde... und direkt im Listen hat man das Problem, dass dann Fehler zurückgegeben werden können, die mit dem Listen an sich gar nicht wirklich was zu tun haben sondern schon viel früher im System auftreten.

--

TheTinySteini
Coder Poke646
"Don't Panic" - Hitchhiker's Guide to the Galaxy

zum Seitenanfang zum Seitenende Profil || Suche
006
12.04.2003, 20:12
Tron



darauf gibt es eine einfache antwort: throw
Quellcode:try
{
  socket MeinSchnuggeligerSocket;
}
catch(const socketerror& SocketError)
{
  // tja, da ist was schiefgelaufen...
}
das paradigmum, alle notwendigen vorbereitungen im konstruktor zu machen, nennt sich uebrigens 'resource acquisition is initalization'.

und solche delphi-maesigen init/destroy-sachen ... das ist pfui-baeh!

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
007
12.04.2003, 21:15
snoopdog



hmm könnt ihr euch vielleicht auch denken warum mein MeinSchnuggeligerSocket
bei mir nix empfängt oder sendet?? Aber bei meinem Bot, wo ich die selbe Klasse nutze, funktioniert alles...

--

Visit our 500er Gamer Lan
@ www.evil-lanparty.de or
@ www.evil-havoc.com
Visit the HaVoc Lanparty Community
@ www.havoc-lanparty.com

zum Seitenanfang zum Seitenende Profil || Suche
008
12.04.2003, 21:54
Tron



ein IRC-bot ist ja nur die client-seite, vermutlich liegt der fehler demnach an deinem server.
starte doch zum beispiel mal deinen server auf und verbinde dich damit per telnet.

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
009
13.04.2003, 11:31
Prefect



snoopdog, die StartServer()-Funktion ist absoluter Käse. Hast du dir überhaupt mal die Dokumentation zu accept() durchgelesen? Du musst natürlich den von accept() zurückgegebenen Socket zum Lesen der Daten verwenden.

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
010
13.04.2003, 12:19
TheTinySteini



Fast... seine SocketRecv()-Funktion ist falsch. Denn die benutzt socket s, statt connectedsocket.

--

TheTinySteini
Coder Poke646
"Don't Panic" - Hitchhiker's Guide to the Galaxy

zum Seitenanfang zum Seitenende Profil || Suche
011
13.04.2003, 13:13
snoopdog



@Tron ja soweit war ich auch schon, hab des auch shcon mit Telnet probiert, da hat er auch nix empfangen.
Danke @TheTinySteini
dummer Fehler, ok nu geht es, thx...

--

Visit our 500er Gamer Lan
@ www.evil-lanparty.de or
@ www.evil-havoc.com
Visit the HaVoc Lanparty Community
@ www.havoc-lanparty.com

zum Seitenanfang zum Seitenende Profil || Suche
012
14.04.2003, 10:59
Prefect



Hmm TTT, was machst du dann in SocketRecv() für den Clientsocket? Der muss ja schließlich auch empfangen. Man kann das Drehen und Wenden wie man will, so wie sie im Moment ist ist die Klasse unsinnig.
Den Listensocket muss man auch einfach anders handeln (es sei denn, man will einen Server, der nur eine einzige Verbindung aufrecht halten kann).

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
013
14.04.2003, 18:27
TheTinySteini



Prefect, darum ging's mir in dem Fall nicht =)
So geht erstmal sein Code, aber wie du ja schon mehrmals unterstrichen hast, wird er davon nicht gut. Ich würd glaub ich eh die Klassen enger fassen. Ne Socket-Klasse mit recv und send usw., und darum dann client bzw. server-Klassen (bzw. Client und Server abgeleitet, sofern das Sinn macht, die Überlegung hab ich mir jetzt auf die Schnelle gespart).

--

TheTinySteini
Coder Poke646
"Don't Panic" - Hitchhiker's Guide to the Galaxy


Dieser Beitrag wurde am 14.04.2003 um 18:28 von TheTinySteini bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche