Anzahl der User im IRC-Channel



  • Hallo,

    ich habe eine bereits fertige Anwendung, würde dazu aber gerne eine Liste mit den Benutzern hinzufügen, die momentan online sind.
    Ich möchte einmal die Gesamtanzahl und auch eine Liste mit den usernamen (vllt. auch mit Status, also @ % usw...) Leider habe ich keine Ahnung wie ich das angehen soll, da ich keine IRC-Client-Komponente im bcb habe und die Befehle con IRC nicht kenne.
    Der Code soll auch nicht noch mehr können.

    Freue mich über jede hilfe



  • Die Kommandos habe ich nun:

    1. verbinden
    2. USER benutzername * 0 :Max Mustermann
    3. NICK benutzername
    4. Server sollte PING :ZAHL senden
    5. Ich sollte PONG :ZAHL senden

    Leider bekomme ich vom Server anscheinend keine Antwort mehr.
    Ich sollte eigentlich nach NICK benutzernamen eine zeile erhalten.
    Über telnet erhalte ich Sie, nicht aber über mein Socket.

    Beim Aufbau der Verbindung erhalte ich allerdings 4 Zeilen Text.



  • Es gibt Befehle die Dir einfach eine Benutzerliste des Chanels liefern genauso
    wie ein Befehl der dir ziemlich viele Informationen über Server/Client/Channels gibt aber wie die genau hießen? Gute Frage, falsches Forum!

    Du solltest dich da glaube ich eher an ein IRC Forum wenden.

    Trotzdem würde es mich interessieren wie Du es realisiert hast zu einem IRC-Server zu verbinden.

    Move?



  • Wie ich daran komme, das weiß ich nun:
    NAMES #cannel

    Wie ich damit verbunden habe?
    Ganz einfach:

    Ich habe einen TClientSocket genommen,
    unter HOST habe ich irc.host.de eingegebeben.
    Unter Port 6667
    Dann habe ich über ClientSocket1->Open() die Verbindung hergestellt.
    Bei OnClientRead wird der emfangene Text in ein Memo geschrieben (nur zum debuggen):
    Memo1->Lines->Add(Socket->RevieveText());

    Ganz einfach, oder?

    Aber, mein Problem besteht weiterhin:
    ich erhalte vom Server anscheinend keine Antwort mehr, oder mein Text kommt nie an.
    Ich sollte eigentlich nach "NICK benutzername" eine zeile erhalten.
    Über telnet erhalte ich Sie, nicht aber über mein Socket.

    Beim Aufbau der Verbindung erhalte ich allerdings 4 Zeilen Text.
    Und beim Timeout durch den IRC-Server auch.



  • Hallo

    Ich weiß nicht ob TClientSocket wirklich geeignet ist um IRC anzusprechen. Normalerweise ist es dafür gedacht mit einem Server zu arbeiten auf dem TServerSocket drauf ist.
    Entweder schaust du dich nach externen Librarys um die IRC-Zugriffe ermöglichen, zum Beispiel das Indy-Packet in dem TIdIRC vorhanden ist. Oder du verwendest einfache Sockets aus der WinAPI, damit sollte eine ungestörte Verbindung möglich sein.

    bis bald
    akari



  • Ok, aber:

    1. Ich habe zwar die Indy-Komponenten, aber der IRC-Client fehlt, den Server hätte ich.
    2. Ich habe keine Anung, wie ich das mit Winsockets realisieren könnte


  • Hallo

    IRC Man schrieb:

    Ok, aber:

    1. Ich habe zwar die Indy-Komponenten, aber der IRC-Client fehlt, den Server hätte ich.

    Bei meinen Nachträglich installiertem Indy9 ist unter Clients TIdIRC.

    1. Ich habe keine Anung, wie ich das mit Winsockets realisieren könnte

    Da must du im WinAPI Forum nachschauen.

    bis bald
    akari



  • Normalerweise ist es dafür gedacht mit einem Server zu arbeiten auf dem TServerSocket drauf ist.

    Quatsch.



  • Also, ich habe jetzt einen Code, und der funktioniert auch unter Konsolenapplikationen.
    Unter VCL, bekomme ich fehler, weil er die befehle fgets usw... nicht kennt.
    Leider weiß ich aber auch nicht, wie ich den Code anders formulieren kann.

    Der cODE.

    #include <stdio.h> //Lasse ich bei der Anwendung mit Fenster weg
    #include <string.h> //Lasse ich bei der Anwendung mit Fenster weg
    #include <windows.h>
    #include <winsock.h>
    
    #define BUF_SIZ 4096
    
    void cut(char *s)
    {
        while (*s && (*s != '\r') && (*s != '\n'))
            s++;
        *s = '\0';
    }
    
    DWORD WINAPI reader(PVOID pParam)
    {
        char line[BUF_SIZ];
        SOCKET s;
    
        s = *(SOCKET*)pParam;
    
        while(fgets(line, sizeof(line) - 3, stdin)) //FEHLER, fgets und stdin nicht gefunden
        {
            cut(line);
            strcat(line, "\r\n");    /* passt sicher */
            if (send(s, line, strlen(line), 0) == -1)
                return 1;
        }
    
        return 0;
    }
    
    DWORD WINAPI writer(PVOID pParam)
    {
        char  buffer[BUF_SIZ];
        int bytes;
        SOCKET s;
    
        s = *(SOCKET*)pParam;
    
        while((bytes = recv(s, buffer, sizeof(buffer), 0)) > 0)
            fwrite(buffer, 1, bytes, stdout); //fwrite und stdout findet er nicht. 
    
        return 0;
    }
    
    int main(int argc, char *argv[])
    {
        HANDLE threads[2];
        unsigned long id;
        struct sockaddr_in addr;
        struct hostent *host;
        SOCKET s;
        WSADATA wsa;
    
        if (argc != 3) //arc kennt er auch nicht, aber das "Problem" ist gelöst
        {
            fprintf(stderr, "usage: %s <Host> <Port>\n", argv[0]); //fprintf und stderr und argv kennt er nicht, fällt aber auch weg
            return 1;
        }
    
        if (WSAStartup(MAKEWORD(1, 1), &wsa))
        {
            fprintf(stderr, "WSAStartup() failed: %i\n", WSAGetLastError());
            return 2;
        }
    
        if ((addr.sin_addr.s_addr = inet_addr(argv[1])) == -1)
        {
            host = gethostbyname(argv[1]);
            if (!host)
            {
                fprintf(stderr, "gethostbyname() failed: %i\n", WSAGetLastError());
                return 3;
            }
            addr.sin_addr = *(struct in_addr*)host->h_addr;
        }
    
        if ((s = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
        {
            fprintf(stderr, "socket() failed: %i\n", WSAGetLastError());
            return 4;
        }
    
        addr.sin_family = AF_INET;
        addr.sin_port = htons(atol(argv[2]));
    
        printf("connecting to %s\n", inet_ntoa(addr.sin_addr)); //printf kennt er nicht, stellt kein Problem dar
        if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
        {
            fprintf(stderr, "connect() failed: %i", WSAGetLastError());
            return 5;
        }
    
        threads[0] = CreateThread(NULL, 0, reader, &s, 0, &id);
        threads[1] = CreateThread(NULL, 0, writer, &s, 0, &id);
    
        WaitForMultipleObjects(2, threads, FALSE, INFINITE);
    
        closesocket(s);
    
        return 0;
    
    }
    

    Die Fehlermeldungen stehen als Kommentar im Code.
    Ich würde mich SEHR SEHR freuen, wenn ich Hilfe bekomme



  • *PUSH*



  • Hallo

    Naja was willst du nun von uns wissen? Das die C-Funktion fgets im Header stdio.h liegt?
    In C++ sollte dieser Header natürlich so eingebunden werden :

    #include <cstdio>
    std::fgets(...); // Die Funktionen liegen nun im Namespace std
    

    bis bald
    akari



  • Naja, nicht direkt.
    Ich will, dass dieser Code auch in einer nicht-DOS-Fenster Anwendung läuft.
    Das fgets brauche ich dann nicht mehr, da ich die Kommandos die ich senden will kenne.
    Ich will wissen, wie der Code lauten muss, damit er läuft.

    (Ich kann das irgendwie nicht so gut erklären...)



  • Hallo

    Na dann lies doch nach was fgets macht und setzt das in deinem VCL-Projekt um. Ist es so schwer statt dem fgets die Eingabe aus zum Beispiel einen TEdit zu holen und an send zu übergeben?

    bis bald
    akari


Log in to reply