Per fare le prove con i socket ho iniziato in PHP... Ed alla fine il tutto è diventato un BOT per IRC... E il suo dovere lo fa alla grande, però c'è il problema della lentezza, e del fatto che essendo implementato in "maniera sincrona" non posso ricevere o trasmettere dati contemporaneamente!!!
Allora ho pensato di cimentarmi con i socket asincorni in PHP, ma data la natura del linguaggio (sicuramente non progettato per threads etc...), ho deciso di passare al C, e sono più o meno riuscito a realizzare un minimo di quello che facevo con PHP (leggo e trasmetto i dati... E' solo da mettere un po' a posto)... Però rimane sempre un qualcosa di "sincrono"...
Ora, ho letto di threads ed altre cose utili per realizzare programmi con socket asincroni, ma non ho trovato gran che, e tra quel poco che c'è non ci ho capito più di tanto...
Le mie domande sono:
1. Quale linguaggio usare??? PHP bellissimo per gestire le stringhe con explode etc., ma rimane sempre un qualcosa di interpretato... C sarebbe "il mio sogno", ma non ho idea da dove iniziare... Altri linguaggi non ne conosco (a parte il Visual Basic... Mah!!! Lasciamo perdere ) , ma non sarebbe male impararne, sopratutto se il passo non è troppo difficile da seguire!!!
2. Avete qualche guida da consigliare, oppure qualche consiglio da darmi??? Qualche presentazione, qualche PDF, qualche sito...
Intanto vi posto quel poco che sono riuscito a fare di "sincorono" in C ed in PHP...
PHP:
Codice: Seleziona tutto
#!/usr/bin/php
<?php
system("clear");
$debug = 0;
$irc_server = "indirizzo.ip.oppure.nome";
$irc_port = 6667;
$irc_chan = "#nomecanale";
$user_name = "nomeutente";
$user_psw = "VUOTO";
$bad_words = array("directory", "windows", "microsoft", "directory", "bill", "gates");
function send($stream, $data) {
echo " --->> $data";
fwrite($stream, $data);
}
echo "\n\n";
echo "roBOT per IRC\n\n\n";
echo "Riepilogo dati di connessione:\n\n";
echo "Server:\t\t$irc_server\n";
echo "Porta:\t\t$irc_port\n";
echo "Nome canale:\t$irc_chan\n";
echo "Nome utente:\t$user_name\n";
echo "Password:\t$user_psw\n";
echo "\n\n";
echo "Creazione socket... ";
$irc = fsockopen($irc_server, $irc_port, $irc_errno, $irc_errstr, 15);
if ($irc) {
echo "fatto!\n";
} else {
echo "ERRORE!!!!\n";
die($irc_errstr . " ($irc_errno)");
}
echo "\n\n";
send($irc, "USER $user_name \"1\" \"1\" :IRC Bot.\n");
send($irc, "NICK $user_name\n");
while (!feof($irc)) {
$rawdata = str_replace(array("\n","\r"), "", fgets($irc, 512));
$data = str_replace(" ", " ", $rawdata);
echo " <<--- $data\n";
$d = explode(" ", $data);
if (strtolower($d[0]) == "ping") {
if($debug == 1) {
echo " [ deb ] Richiesta di PING...\n";
}
send($irc, "PONG $d[1]\n");
if($debug == 1) {
echo " [ deb ] Risposto!!\n";
}
} elseif ((count($d) > 1) and (($d[1] == "376") or ($d[1] == "422"))) {
if($debug == 1) {
echo " [ deb ] Join del canale $irc_chan...\n";
}
send($irc, "JOIN $irc_chan\n");
if($debug == 1) {
echo " [ deb ] Fatto!\n";
}
send($irc, "PRIVMSG $irc_chan :Ciao a tutti... $user_name e' tornato!\n");
send($irc, "PRIVMSG $irc_chan :Ora controllo il canale!!!\n");
send($irc, "PRIVMSG $irc_chan :Per informazioni dai il comando \"$user_name help\"!!!\n");
} else {
if(count($d) > 3) {
$check = substr($d[3], 1, (strlen($d[3]) - 1));
}
$head = explode("!", $d[0]);
$sender = substr($head[0], 1, (strlen($head[0]) - 1));
if($debug == 1) {
echo " [ deb ] check: $check\n";
echo " [ deb ] cmd: $cmd\n";
echo " [ deb ] sender: $sender\n";
}
for($j=3; $j<count($d); $j++) {
if($j == 3) {
$parola = substr(strtolower($d[$j]), 1);
} else {
$parola = strtolower($d[$j]);
}
for($k=0; $k<count($bad_words); $k++) {
if($debug == 2) {
echo " [ deb ] parola: $parola\n";
echo " [ deb ] bad_words[$k]: $bad_words[$k]\n";
}
if($parola == $bad_words[$k]) {
send($irc, "PRIVMSG $irc_chan :$sender::: La parola $parola non e' ammessa!!!\n");
send($irc, "PRIVMSG $irc_chan :$sender::: Ti prendo a calci!!!\n");
send($irc, "KICK $irc_chan $sender\n");
$kickkati[$sender]++;
send($irc, "PRIVMSG $irc_chan :$sender::: E siamo a $kickkati[$sender]...\n");
if($kickkati[$sender] == 2) {
send($irc, "PRIVMSG $irc_chan :$sender::: Alla terza ti butto FUORI!!!\n");
} elseif($kickkati[$sender] == 3) {
send($irc, "PRIVMSG $irc_chan :$sender::: Ti avevo avertito!!!\n");
send($irc, "PRIVMSG $irc_chan :$sender::: FFUUOORRIIIIIII!!!\n");
send($irc, "MODE $irc_chan +b $sender!*@*\n");
send($irc, "PRIVMSG $irc_chan :Peggio per lui... Si arrangia!!! AHAHAHAH ;)\n");
$kickkati[$sender] = 0;
}
}
}
}
if($check == "$user_name") {
if(count($d) > 4) {
$cmd = $d[4];
if($cmd == "salutami") {
send($irc, "PRIVMSG $irc_chan :Ciao $sender :)\n");
}
if($cmd == "saluta") {
if(count($d) > 5) {
send($irc, "PRIVMSG $irc_chan :Ciao $d[5]... Come stai??\n");
} else {
send($irc, "PRIVMSG $irc_chan :Ciao a tutti!! :)\n");
}
}
if($cmd == "ciao") {
send($irc, "PRIVMSG $irc_chan :Ciao a tutti!! :)\n");
}
if($cmd == "help") {
send($irc, "PRIVMSG $irc_chan :Allora... Ti do l'elenco delle parole vietate!! ;)\n");
$testo_p = "";
for($k=0; $k<count($bad_words); $k++) {
$testo_p = "$testo_p " . $bad_words[$k];
}
send($irc, "PRIVMSG $irc_chan :$testo_p\n");
}
if($sender == "sardylan") {
if($cmd == "debanna") {
if(count($d) > 5) {
send($irc, "PRIVMSG $irc_chan :OK... Debanno $d[5]...\n");
send($irc, "MODE $irc_chan -b $d[5]!*@*\n");
}
}
}
} else {
send($irc, "PRIVMSG $irc_chan :Cosa c'è $sender??\n");
}
}
}
}
?>
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <string.h>
struct irc_param_s {
char *ip_addr;
int *ip_port;
char *usr_id;
char *usr_psw;
char *irc_chan;
};
typedef struct irc_param_s irc_param;
void header();
void footer();
irc_param *create_infos(int, char **);
void summary(irc_param *);
int sock_create_cli(char *, int);
void sck_send(int, FILE *, char *);
char *sck_recv(int, FILE *);
void sock_close(int);
void boter(irc_param *, int);
void chk_response(char *, int);
void header() {
system("clear");
printf("\n\n");
printf("#################################\n");
printf("#### roBOT per IRC ####\n");
printf("#################################\n");
printf("\n\n");
}
void footer() {
printf("\n\n");
printf("Press ENTER to exit... ");
getchar();
printf("\n\n");
}
irc_param *create_infos(int arg_c, char **arg_str) {
int i;
char tmp_param[] = "-a";
irc_param *ret;
int len;
ret = (irc_param *) malloc(sizeof(irc_param));
for(i=1; i<arg_c; i++) {
tmp_param[1] = 's';
if(strcmp(tmp_param, arg_str[i]) == 0) {
i++;
len = strlen(arg_str[i]);
ret->ip_addr = malloc((len * sizeof(char)) + 1);
strcpy(ret->ip_addr, arg_str[i]);
}
tmp_param[1] = 'p';
if(strcmp(tmp_param, arg_str[i]) == 0) {
i++;
len = strlen(arg_str[i]);
ret->ip_port = malloc(sizeof(int));
*ret->ip_port = atoi(arg_str[i]);
}
tmp_param[1] = 'u';
if(strcmp(tmp_param, arg_str[i]) == 0) {
i++;
len = strlen(arg_str[i]);
ret->usr_id = malloc((len * sizeof(char)) + 1);
strcpy(ret->usr_id, arg_str[i]);
}
tmp_param[1] = 'k';
if(strcmp(tmp_param, arg_str[i]) == 0) {
i++;
len = strlen(arg_str[i]);
ret->usr_psw = malloc((len * sizeof(char)) + 1);
strcpy(ret->usr_psw, arg_str[i]);
}
tmp_param[1] = 'c';
if(strcmp(tmp_param, arg_str[i]) == 0) {
i++;
len = strlen(arg_str[i]);
ret->irc_chan = malloc((len * sizeof(char)) + 1);
strcpy(ret->irc_chan, arg_str[i]);
}
}
return ret;
}
void summary(irc_param *infos) {
printf("\n");
printf("Summary of parameters:\n\n");
printf("IRC Server Address:\t\t%s\n", infos->ip_addr);
printf("IRC Server Port:\t\t%d\n", *infos->ip_port);
printf("User ID:\t\t\t%s\n", infos->usr_id);
printf("User password:\t\t\t%s\n", infos->usr_psw);
printf("IRC Channel name:\t\t%s\n", infos->irc_chan);
printf("\n");
}
int sock_create_cli(char* addr, int port) {
printf("Creating socket... ");
struct sockaddr_in temp;
struct hostent *h;
int sock;
int errore;
temp.sin_family = AF_INET;
temp.sin_port = htons(port);
h = gethostbyname(addr);
if(h == 0) {
printf("Gethostbyname fallito\n");
exit(1);
}
bcopy(h->h_addr, &temp.sin_addr, h->h_length);
sock = socket(AF_INET, SOCK_STREAM, 0);
errore = connect(sock, (struct sockaddr*) &temp, sizeof(temp));
printf("done!\n\n");
return sock;
}
void sock_close(int sock) {
close(sock);
return;
}
void sck_send(int sock, FILE *fp, char *text) {
if(strlen(text) > 0) {
char *out;
out = malloc(strlen(text) + 1);
sprintf(out, "%s\n", text);
fprintf(fp, " -->> %s", out);
write(sock, out, strlen(out), 0);
}
}
char *sck_recv(int sock, FILE *fp) {
char buff[2048];
char *ret;
int len;
read(sock, buff, sizeof(buff));
fprintf(fp, " <<-- %s\n", buff);
len = strlen(buff);
ret = malloc((len * sizeof(char)) + 1);
strcpy(ret, buff);
return ret;
}
void boter(irc_param *infos, int sck) {
char *cmd;
char *out;
cmd = malloc(2048 * sizeof(char));
printf("Starting communications with server... \n\n");
sprintf(cmd, "USER %s \"1\" \"1\" :IRC Bot.", infos->usr_id);
sck_send(sck, stdout, cmd);
sprintf(cmd, "NICK %s", infos->usr_id);
sck_send(sck, stdout, cmd);
do {
out = sck_recv(sck, stdout);
chk_response(out, sck);
} while(1);
printf("Ciao\n");
}
void chk_response(char *out, int sck) {
char cmd[2048];
char tmp_cmd[2048];
int cmd_chk;
int i;
int ln;
sprintf(cmd, "PING");
cmd_chk = strncmp(out, cmd, 4);
if(cmd_chk == 0) {
ln = strlen(out);
for(i=0; i<(ln-4); i++) {
tmp_cmd[i] = *(out + (i + 4));
}
sprintf(cmd, "PONG%s", tmp_cmd);
sck_send(sck, stdout, cmd);
}
}
int main(int argc, char **argv) {
irc_param *param;
int sck_des;
if(argc < 10) {
printf("\n");
printf("Usage: %s -s <server> -p <port> -c <channel> -u <user-id> -k <user-psw>\n\n", argv[0]);
return 0;
}
header();
param = create_infos(argc, argv);
summary(param);
sck_des = sock_create_cli(param->ip_addr, *param->ip_port);
boter(param, sck_des);
footer();
return 0;
}
Usando il C, la cosa funziona più o meno allo stesso modo??? Oppure sono completamente fuori strada??
Vi ringrazio tutti in anticipo!!!
P.S. Non badate al modo di programmare ... Sono un "maniaco" delle tabulazioni e mi piacciono le cose ordinate