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");
}
}
}
}
?>
C:
- 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;
}
Quando avevo provato una cosa simile su Windows, usavo Visual Basic 6... Mettevo un controllo socket ed in automatico venivano richiamate delle "sub" ad ogni occorrenza di un evento (ricezione dati, connessione avvenuta, etc...). Inserivo il codice nelle sub che mi interessavano e gestivo il tutto in questo modo...
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 




comunque ti posso consigliare la procedura che ho sempre usato:

