|
|
|
|
Strumenti |
03-07-2014, 09:48 | #21 |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
Io pensavo ad unica send in cui inviavo un buffer
char *buffer[256] fino alla lunghezza riempita 5cpippo E di là 1 recv per ricevere 5c (cavolo in effetti sono due byte rischierei un errore) e un altra recv con len 5 per ricevere pippo . In effetti è una soluzione sparta da bimbiminkia Indeciso tra questa soluzione e tra l'inviare due send una per la lunghezza e una per il msg + usare una variabile per gli stati Devo scegliere una via e portarla avanti senza guardarmi indietro Ultima modifica di aeroxr1 : 03-07-2014 alle 09:51. |
03-07-2014, 10:50 | #22 | |
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Quote:
C and C++, where (almost) everything is not what it seems... Ultima modifica di van9 : 03-07-2014 alle 21:41. |
|
03-07-2014, 11:04 | #23 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Sì scusate, non stavo tenendo conto della select.
Il codice rimane quello, con l'aggiunta del controllo su FD_ISSET e il settaggio delle opportune variabili di stato, che a mio parere sono obbligatorie. La dimensione del buffer di invio è irrilevante, mentre in ricezione te ne servono 2 di buffer: uno per dimensione oaylod + comando (se ha dimensione fissa) e il secondo che allochi a runtime in base a ciò che hai ricevuto. Questo vuol dire che oltre al file descriptor, il server deve mantenere, per ogni connessione, la dimensione del payload, il comando e il buffer del payload (almeno parziale). Ti suggerirei una struct che contenga il tutto e funzioni per serializzare/deserializzare i suoi dati. Se questa soluzione non ti piace, puoi dare uno sguardo all'opzione del socket SO_RCVLOWA che ti permette di impostare il valore minimo in byte di soglia necessario a far ritornare la select. Non ho mai provato e non mi sento di consigliarlo.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
03-07-2014, 11:24 | #24 | ||
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Quote:
Quote:
Ribadisco anche io la necessità di una variabile di stato per ogni connessione, naturalmente solo sul client. |
||
03-07-2014, 11:57 | #25 |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
ok quindi credo farò così :
- due send una fissa di un byte con la dimensione del campo successivo che verrà inviata con la send subito dopo - sul server terrò una lista con un elemento per ogni client , contenente i vari buffer per ogni client e la variabile di stato che mi dirà in che punto sono della comunicazione client server - la variabile comando potrei inviarla successivamente tanto il primo comando è per forza di cose l'invio dello username - dopo negli invii successivi andrò a vedere cosa c'è nel campo data e qui ci sarà il comando e per ogni comando mi sposterò nello stato opportuno Fin qui ragiono male ? (poi per carità lo deve vedere in pratica, però l'idea sarebbe questa ) per serializzare i dati della struct che andrò ad inviare passo passo, dato che la mia struct conterrà solo caratteri [username e comandi] e numeri interi , potrei usare per questi ultimi le semplici funzioni htons() , ntohs() , htonl() e ntohl() ? E un ultima cosa la creazione del buffer dinamico sul server, io inizialmente pensavo di creare una struttura con all'interno un campo username[256], comando ecc ecc. Allocando staticamente i vettori con uno spazio grande a sufficienza, e non usare la creazione dinamica, poichè non sono capace a creare un allocazione dinamica di stringhe-vettori in C , però mi rendo conto che lo spreco è alto Vabbè sarà il caso di capire come creare allocazione dinamica di vettori |
03-07-2014, 12:15 | #26 |
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
No, dai, studia prima l'allocazione dinamica e poi ti cimenti coi socket!
Per il futuro, quando vorrai fare delle ottimizzazioni, ricordati di non allocare e deallocare continuamente, sono operazioni che costano, pensa bene dove vale la pena risparmiare e accorpa quello che si può accorpare. |
03-07-2014, 12:18 | #27 |
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
|
03-07-2014, 12:30 | #28 | |||
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Quote:
Quote:
Quote:
|
|||
03-07-2014, 12:36 | #29 | |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
Quote:
Quindi non so di quanto spazio allocare in memoria con la malloc Cercando su internet ho letto della funzione realloc, in pratica gli si assegna un blocco di dimensioni x e poi se non basta con la realloc si riassegna un altro spazio contiguo (se esiste , già questa cosa mi lascia perplesso ) . Però non ho trovato la maniera di creare un buffer perfettamente adatto all'input. Però riflettendoci in questo caso saprei quanti byte mi arrivano quindi creo una porzione per quei byte e la riempio Il problema è più sul client , però li metto un buffer grande e grosso |
|
03-07-2014, 13:20 | #30 |
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
La programmazione lascia abbastanza spazio alla fantasia, dipende dalla logica che vuoi utilizzare, comunque non restare nell'indecisione, intraprendi una strada che ritieni corretta, poi se ti si presenteranno dei problemi troverai il modo di affrontarli. Anche se commetti un errore non ti avvilire, sbagliando si impara
|
03-07-2014, 13:39 | #31 |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
Non avessi sempre delle scadenze vicine da rispettare il tutto sarebbe meno stressante
COmunque grazie a tutti Provo un pò a mettere le mani nel codice vediamo che ne viene fuori Mi farò sicuramente risentire per rompervi le scatole con altri dubbi |
03-07-2014, 14:00 | #32 |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
Non avessi sempre delle scadenze vicine da rispettare il tutto sarebbe meno stressante
COmunque grazie a tutti Provo un pò a mettere le mani nel codice vediamo che ne viene fuori Mi farò sicuramente risentire per rompervi le scatole con altri dubbi |
03-07-2014, 16:15 | #33 | ||
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Quote:
Quote:
|
||
03-07-2014, 16:20 | #34 |
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Un ottimo motivo per imparare a usare da subito librerie di qualità comprovata come Vstr o Bstring, e poi studiarsene gli internals e scriversi le proprie per imparare.
|
03-07-2014, 19:37 | #35 | |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
Quote:
In molti forum se avessi chiesto le stesse cose mi avrebbero dato dell'ignorante , voi invece mi avete dato una grande mano ! Grazie veramente di cuore |
|
05-07-2014, 01:52 | #36 |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
Prendendo un pò di vostri suggerimenti ho iniziato a cercare di mettere in pratica questa idea:
Lato Client: - send comando (1byte) - send dimensione dati (1byte) - send dati (dimensione variabile) Lato Server: - recv comando (1byte) - recv dimensione dati (1byte) - recv dati (dimensione variabile) una struttura lato server contenente : - variabile comando - variable lunghezza dati - buffer dinamico contentente i dati - variabile di stato la variabile di stato pensavo di farla da 0 a 3 dove 0 attesa comando, 1 attesa dimensione dati , 2 attesa dati, 3 esecuzione comando (forse lo stato 3 è evitabile) - Voi che dite sono troppe tre recv due delle quali usate per ricevere un byte per volta ? - e anche la variabile lunghezza dati pensavo di inviarla sempre anche quando il campo dati contiene un dato di dimensione 0 cioè vuoto e quando il campo dati contiene 1 solo byte . Dite che è uno spreco ? |
05-07-2014, 08:49 | #37 |
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
La struttura sul server deve avere un'ulteriore variabile che conserva la lunghezza dei dati effettivamente ricevuti, perché il server deve rimanere nello stato "2 attesa dati" fino a quando i dati ricevuti raggiungono la lunghezza dati prevista.
Sul client vale lo stesso discorso, e non avendo il problema di dover gestire più connessioni puoi mettere la recv in un loop. Lo stato 3 lo eviterei, quando i dati ricevuti raggiungono la lunghezza prevista puoi eseguire il comando e reimpostare lo stato zero. Per me non c'è alcun motivo per non usare una recv per ogni dato. La lunghezza dato la invierei sempre, in questo modo non c'è bisogno di controllare che tipo di comando è arrivato. |
05-07-2014, 09:13 | #38 |
Senior Member
Iscritto dal: Mar 2006
Messaggi: 2056
|
Esatto la lunghezza dato pensavo proprio di inviarla sempre per quel motivo se no dovrei fare un doppio controllo sul comando.
E la variabile che hai detto mi ero scordata di scriverla XD Io però lato server hi creato una struttura ad hoc per ogni client mentre lato client no. Sulla serializzazione delle strutture non avendolo mai fatto mi incuriosisce , ma dovrei informarmi . Lato client c'è una connessione UDP verso un altro client Devo un attimo riflettere se mentre riceve ha bisogno anche di comunicare con l'altro client o no. In caso positivo devo gestire la recv per evitare il loop :/ Vedrò ! Inviato dal mio Galaxy Nexus utilizzando Tapatalk |
05-07-2014, 09:43 | #39 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12646
|
Quote:
Ora giusto per curiosità provo sulle ultime versioni di clang e Visual Studio 2013 . Edit: neanche Visual Studio si lamenta (sempre abilitando tutti i Warning), sarà perché usa un compilatore C++. Edit2: neanche llvm 3.4, sempre passando -Wall -Wextra. In pratica possiamo buttare tutti i compilatori esistenti . Ultima modifica di WarDuck : 05-07-2014 alle 09:54. |
|
05-07-2014, 12:45 | #40 | ||
Senior Member
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
|
Quote:
Quote:
__________________
In a world without fences, who needs Gates? Power by: Fedora 8 - Mac OS X 10.4.11 Ultima modifica di nico159 : 05-07-2014 alle 12:48. |
||
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 10:06.