PDA

View Full Version : [C++, Qt] I/O terminale


Teo@Unix
24-02-2010, 13:03
Ciao,

sto scrivendo un semplice client su console in stile telnet.
Però sto utilizzando le librerie Qt e scrivendo in C++, dato che vorrei compilarla per più piattaforme.

In C per l'I/O utilizzavo la solita select() e gestivo con le relative macro il multiplexing.... su Qt non dovrebbe essere molto diverso a parte essere più semplice, a quanto vedo con TCPSocket devo usare il metodo ReadyRead() giusto?

Il punto è con stdout e stdin come faccio? Devo abbinare questi ad un oggetto QIODevice? Non avreste un esempio ?

Il codice C da implementare è tipo il seguente:
void
prompt(FILE* fp, int sock)
{
int maxfd;
char send_buffer[BUFF_SIZE], recv_buffer[BUFF_SIZE];
fd_set rset;

FD_ZERO(&rset);
while(1)
{
FD_SET(fileno(fp),&rset);
FD_SET(sock,&rset);
maxfd = MAX(fileno(fp),sock)+1;
select(maxfd,&rset,NULL,NULL,NULL);
if(FD_ISSET(sock,&rset))
{
memset(recv_buffer,0,sizeof(recv_buffer));
if(read(sock,recv_buffer,BUFF_SIZE) <= 0)
{
perror("read");
exit(-1);
}
fprintf(stdout,"%s\n$ ",recv_buffer);
fflush(stdout);
}

if(FD_ISSET(fileno(fp),&rset))
{
memset(send_buffer,0,sizeof(send_buffer));
if(fgets(send_buffer,BUFF_SIZE,fp) == NULL)
return;
if(write(sock,send_buffer,strlen(send_buffer)+1) <= 0)
{
perror("write");
exit(-1);
}
}
}
}

cionci
24-02-2010, 19:08
QTextStream cout(stdout);

cout << etc etc

Teo@Unix
24-02-2010, 22:37
grazie, ma ... sarà l'ora e la stanchezza ma mi si blocca su readline()...

QString inText, temp;
QTextStream data(stdout);
QByteArray sendBuf;
// ............
while(1)
{
while(sock.bytesAvailable())
{
// ........
}
inText.clear();
do{
inText = data.readLine();
} while(!inText.isNull());
sendBuf.append(inText);
sock.write(sendBuf);
}
// .......

cionci
25-02-2010, 06:41
Direi che sia una cosa normale se apri stdout e ci leggi invece di scriverci :D

Teo@Unix
25-02-2010, 08:02
....:fagiano: ...ops

.... come vedi dal codice..... devo mettere in un QByteArray ed inviare su un socket ciò che l'utente scrive sulla console....

cionci
25-02-2010, 08:04
Devi aprire stdin in tal caso.

Teo@Unix
25-02-2010, 08:36
si, si ma infatti.... guarda il codice è così
QTextStream data(stdin);
QByteArray sendBuf;

while(1)
{
while(sock.bytesAvailable())
{
memset(buffer,0,sizeof(buffer));
sock.read(buffer,256);
cout << buffer;
}

// Però qui non so come usare data

sock.write(sendBuf);
}

non ho ben capito come usare poi QTextStream data

cionci
25-02-2010, 08:38
Come faresti con cin ;) Leggi una QString o carattere per carattere.

Teo@Unix
25-02-2010, 09:02
:eek: sarà che lo faccio sempre con il C...
while(1)
{
while(sock.bytesAvailable())
{
memset(buffer,0,sizeof(buffer));
sock.read(buffer,256);
cout << buffer;
}
do
{
data >> buffer;
sendBuf.append(buffer,sizeof(buffer));
} while (sendBuf.isNull());
sock.write(sendBuf);
}

rimane in eterno su data >> buffer e io posso scrivere sulla console.

cionci
25-02-2010, 09:13
Devi dare invio ;)
Io ti consiglio di leggere una QString e poi copiare i dati nel buffer prima dell'invio (se l'input è maggiore di 256 byte ci potrebbero volere più write).

Teo@Unix
25-02-2010, 09:25
abbi pazienza .... ... c'è anche da considerare che il server è su linux
mentre questo client è su windows, quindi credo ci sia anche il problema del carattere di fine stringa....
considerando che quando faccio invio viene inserito "\n" su windows, prima di inviare sostituisco con "\r", poi dovrò fare l'inverso in ricezione... ma per il momento sarebbe bello tornasse qualcosa....:D ...

ho scritto così mò... ma nulla appare dopo il mio input
# ls

# ls
.... eccc.... ma nessun ritorno, non credo che i dati vengano inviati sicuramente il server risponderebbe quello è già testato...

while(1)
{
while(sock.bytesAvailable())
{
memset(buffer,0,sizeof(buffer));
sock.read(buffer,sizeof(buffer));
cout << buffer;
}
do
{
cout << endl << "# ";
data >> buffer;
buffer[qstrlen(buffer)-1] = '\r';
sendBuf.append(buffer,sizeof(buffer));
} while (sendBuf.isEmpty());
sock.write(sendBuf);
}

EDIT: rettifico i dati non vengono nemmeno inviati

Teo@Unix
25-02-2010, 13:14
data >> buffer;

scusa non dovrebbe ritornare quando do invio qui?

cionci
25-02-2010, 14:01
Leggi con una QString. In quel caso secondo me funziona come il cin nel C++, Ritorna quando dai invio, ma legge solo fino al primo spazio.
Ci sono tante alternative. Guardati un po' QTextStream. Ad esempio il metodo readLine.

Teo@Unix
25-02-2010, 21:09
niente da fare...
a questo punto non ho idea di cosa provare...

while(1)
{
while(sock.bytesAvailable())
{
memset(buffer,0,sizeof(buffer));
sock.read(buffer,sizeof(buffer));
cout << buffer;
}
cout << endl << "# ";
sendBuf.append(data.readLine());
sock.write(sendBuf);
}

a me così pare giusta....

cionci
26-02-2010, 01:29
Anche a me...