Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Linux/Unix ::  IrcClient / Bot     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
lafumafin
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.10.2016
Beiträge: 4
Beitrag lafumafin Mitglied 17:14:46 26.10.2016   Titel:   IrcClient / Bot            Zitieren

Hallo, ich bin Linux User, deshalb steht es hier :D wusste nicht wohin sonst weil C++ ist es ja nicht pur.

Zumindest bin ich dabei einen IrcBot zu erstellen, mein "Bot" holt sich auch die IP vom angegebenen IRC Server vom DNS, aber er schafft es nicht sich zu verbinden. Ich bin nicht so alt und weis daher noch nicht wirklich viel, also bitte nicht sauer sein wenn ich hier was falsches poste.

Kann sich mal jemand bitte meinen Code ansehen, ich finde meinen Fehler nicht!
!Achtung! Das sind NICHT meine Hausaufgaben. In der Schule machen wir nur Java :leak:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * IrcBot Ralphi
 *  
 * –––––––––––––––––––––––––––––
 * Notizen:
 * RFC zu IRC: http://www.ietf.org/rfc/rfc1459.txt
 *
 *
 * TODO:
 * Bis her connectet er nicht zum Channel, TCP geht aber bis hinter den Router, mit WShark überprüft!
 * Er holt sich auch die IP vom DNS, aber ab dann versucht er vergeblich zu verbinden. IP stimmt aber und ist online.
*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
const unsigned int MAX_LINE = 1024; // Groesse des Empfangspuffers - 1024 klingt gut.
using namespace std;
 
int sockfd;
 
 
 
void irc_disconnect() //IRC disconnect
{
    close(sockfd);
}
 
// sendet an den "uplink"
void s2u(const char *msg)
{
    send(sockfd, msg, strlen(msg), 0); //send mademoiselle
}
 
// Verbinden to the IRC server
void irc_connect()
{
   
    const int PORT = 6667;  //6668 bringt selbes resultat
    const char *HOST = "irc.ipv6.quakenet.de"; 
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
   
    if(static_cast<int>(sockfd) < 0)
    {
        perror("socket()");
        irc_disconnect(); // bye bye
        exit(1);
    }
   
    hostent *hp = gethostbyname(HOST); // pointer auf den Hostname
   
    if(!hp)
    {
        cerr << "gethostbyname()" << endl;
        irc_disconnect();
        exit(1);
    }
   
    sockaddr_in sin;   
    memset((char*)&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    memcpy((char*)&sin.sin_addr, hp->h_addr, hp->h_length);
    sin.sin_port = htons(PORT);
    memset(&(sin.sin_zero), 0, 8*sizeof(char));
   
    if(connect(sockfd, (sockaddr*) &sin, sizeof(sin))==-1)
    {
        perror("connect()");
        irc_disconnect();
        exit(1);
    }
}
 
// Des Agentens Identität
void irc_identify()
{
    s2u("NICK RalphiBot - Alpha vrs. 1.0\r\n"); // Nickname
    s2u("USER Bot356767\r\n"); // Userdaten
   
    // TODO: fix - irgendwann hinzufügen, zum dev einfacher ohne
   
    //s2u("PRIVMSG NickServ IDENTIFY password\r\n"); // Identifizieren
   
    s2u("JOIN #nyan\r\n"); // Channel betreten
    s2u("PRIVMSG #nyan :Hello!\r\n"); // Begruessungsnachricht
   
    // TODO: add Channeluser liste runterladen
}
 
// Ping Pong
void ping_parse(const string &buffer)
{
    size_t pingPos = buffer.find("PING");
    if(pingPos!=string::npos)
    {
    string pong("PONG"+buffer.substr(pingPos+4)+"\r\n");
    cout << pong;
    s2u(pong.c_str());
    }
}
void bot_functions(const string &buffer)
{
    size_t pos = 0;
    if((pos=buffer.find(":say "))!=string::npos) // finden wir "say" ?
    {
    s2u(("PRIVMSG #nyan :"+buffer.substr(pos+5)+"\r\n").c_str()); // repeat im channel
    }
    else if(buffer.find(":luca@2a01:4020:1:7::7")==0 && buffer.find("exit")!=string::npos) // nur wir können es stoppen
    {
        s2u("PRIVMSG #nyan :Cya\r\n"); 
        irc_disconnect();
        exit(0);
    }
}
 
// parsing
void irc_parse(string buffer)
{
    if(buffer.find("\r\n") == buffer.length()-2)
    buffer.erase(buffer.length()-2);
    ping_parse(buffer);
    bot_functions(buffer);
}
// Main muss hier runter unter alles drunter...sonst --> declare Fehler -ô.O-
int main()
{
irc_connect();
irc_identify();
 
    for(;;) // recv
    {
        char buffer[MAX_LINE+1] = {0};
        if(recv(sockfd, buffer, MAX_LINE*sizeof(char), 0)<0)
        {
        perror("recv()");
        irc_disconnect();
        exit(1);
        }
        cout << buffer;
        irc_parse(buffer);
    }
    irc_disconnect();
}


Grüße und Danke schon mal

Fin

_________________
Available at quakenet.org #xo


Zuletzt bearbeitet von lafumafin am 17:37:37 26.10.2016, insgesamt 1-mal bearbeitet
Vermuter
Unregistrierter




Beitrag Vermuter Unregistrierter 09:13:26 27.10.2016   Titel:              Zitieren

Hi,

ich vermute, dass es daran liegt, dass du AF_INET nimmst, aber offenbar zu einer IPv6-Adresse verbinden willst (das lässt zumindest die Domain vermuten: irc.ipv6.quakenet.de). Probier doch mal AF_INET6 an beiden Stellen, an denen du momentan AF_INET nimmst.
Vermuter
Unregistrierter




Beitrag Vermuter Unregistrierter 09:21:54 27.10.2016   Titel:              Zitieren

Da scheint aber noch mehr nicht zu passen.

Z. B. castest du hier sin.sin_addr in einen char *:

Code:
memcpy((char*)&sin.sin_addr, hp->h_addr, hp->h_length);


Das sieht für mich falsch aus. sin_addr ist vom Typ struct in_addr, was wiederum laut http://www.gta.ufrj.br/en ....... ckets/sockaddr_inman.html das hier ist:

Code:
struct in_addr {
    unsigned long s_addr;  // load with inet_aton()
};


Du schreibst also da, wo ein Struct hin gehört, das eine unsigned long (s_addr) enthält, eine Zeichenkette (hp->h_addr) hin.

Google mal lieber nach "c socket ipv6" und schau dir da ab, wie die das machen.


Außerdem solltest du laut http://man7.org/linux/man-pages/man3/gethostbyname.3.html lieber eine andere Funktion als gethostbyname verwenden:

http://man7.org/linux/man-pages/man3/gethostbyname.3.html schrieb:
The gethostbyname*(), gethostbyaddr*(), herror(), and hstrerror()
functions are obsolete. Applications should use getaddrinfo(3),
getnameinfo(3), and gai_strerror(3) instead.
lafumafin
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.10.2016
Beiträge: 4
Beitrag lafumafin Mitglied 17:49:51 27.10.2016   Titel:              Zitieren

Vielen Dank, ich probier mal weiter rum, Google ist mein Freund :D

_________________
Available at quakenet.org #xo
Ratgeber-Amateur
Unregistrierter




Beitrag Ratgeber-Amateur Unregistrierter 18:42:30 27.10.2016   Titel:              Zitieren

struct hostent hat einen char** h_addr_list, das ist eine Liste von in_addr's, die du eigentlich nur noch casten musst.

Habe deinen Code mal überflogen und da fallen mir eigentlich ein paar Dinge auf, die mir nicht gefallen. Erstens, packst du in deine sockaddr_in.sin_zero ein weiteres Mal lauter Nullen rein obwohl du doch die Struktur mit lauter Nullen initialisiert hast. Hasts also einmal zu viel drin. Dann castest du auch noch einen Integer in einen Integer, obendrein ein C++-Cast. aber naja, ist wohl Geschmacksache.

Desweiteren rate ich dir entweder eine Bibliothek zu benutzen oder das IRC Protokoll erstmal anständig zu implementieren, bevor du einen Bot baust. Gut, wenns nur mal so dahingeschissen sein soll, ok, aber wenn du einen anständigen Bot schreiben willst bräuchtest du ne Lib dafür. Schreib dir zumindest nen Parser für die Nachrichten.

Und noch was: Ich sag ja nicht, dass du bei solchen Sachen kein C mit C++ mischen sollst, aber so wie du es machst, ist es ziemlich Kacke. Du benutzt kein OO, keine STL, keine kluken Pointer und nichts von alledem. That's not good practice in C++. Wenn du dir wirklich was von dem Programm erwartest, dann schreib es nochmal komplett um, so, dass es besser wartbar und konsistenter ist.

Ahja, und dann noch AF_INET6, falls der Server an den du dich zu verbinden versuchst wirklich nur mit IPv6 Adressen arbeitet.

Und da gibt es auch noch Inkonsistenzen, beim Parsen deiner Nachrichten.
C++ Forum :: Linux/Unix ::  IrcClient / Bot   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.