|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
[C/C++] Socket
ciao,
sto usando le socket per un programma e mi sono accorto di non aver compreso bene il funzionamento. Ho preso in affitto del codice Client e del Codice server per Borland Builder 6.0 e ne è venuto fuori una cosa del tipo: Server void __fastcall TForm1::FormCreate(TObject *Sender) { ServerSocket1->Port = 5000; ServerSocket1->Active = True; } questo quando viene lanciato il programma e suppongo che il server rimanga sempre in ascolto void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender, TCustomWinSocket *Socket) { Socket->SendText(Edit1->Text); } questo evento invece quando un client si connette per sperimentare poi ho voluto aggiungere questo semplice codice in un Button void __fastcall TForm1::Button1Click(TObject *Sender) { for(int i=0; i < 5; i++) { Sleep(1000); Form1->ServerSocket1->Socket->SendText(i); } } Quello che ottengo è un funzionamento corretto fino al Welcome e un disallineamento tra Client/Server quando clicco sul pulsante. Nel client il codice è il seguente: void __fastcall TForm1::FormCreate(TObject *Sender) { ClientSocket1->Port = 5000; ClientSocket1->Host = "127.0.0.1"; ClientSocket1->Active = True; } allo start del client void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket) { if( ClientSocket1->Active ) Edit1->Text = Socket->ReceiveText(); } quando il client si connette al server void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket) { if( ClientSocket1->Active ) Edit1->Text = ClientSocket1->Socket->ReceiveText(); } quando il server invia al client dei messaggi Cosa è sbagliato concettualemnte in questo codice? Non è forse vero che una volta che il client ha creato una connessione attende messaggi dal server? |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12944
|
Se stai sotto Windows immagino che ti convenga dare un'occhiata alle API WinSock2.
http://msdn.microsoft.com/en-us/libr...=VS.85%29.aspx Nota: queste sono le API native del SO. |
|
|
|
|
|
#3 | ||||
|
Member
Iscritto dal: May 2009
Messaggi: 186
|
Qualche suggerimento:
Quote:
Quote:
Codice:
for (int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++)
{
ServerSocket1->Socket->Connections[i]->SendText(String(i));
}
Quote:
Quote:
HTH, |
||||
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
Quote:
|
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
Quote:
scusa in questo caso ServerSocket1->Socket->Connections[i]->SendText(String(i)); devo conoscere il numero di connessioni attive giusto? Non ho trovato una cosa del tipo: ServerSocket1->Socket->Connections[i]->Count(); Il messaggio quando si connette era solo un esperimento. p.s. credo di aver trovato Label1->Caption=ServerSocket1->Socket->ActiveConnections; Ultima modifica di misterx : 17-10-2011 alle 14:02. |
|
|
|
|
|
|
#6 |
|
Member
Iscritto dal: May 2009
Messaggi: 186
|
Sì, beh, c'era anche nel mio esempio...
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
|
|
|
|
|
|
#9 | |
|
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
|
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
grazie per la dritta.
Ho ancora unda domanda: come gestisco le disconnessioni del client in quanto ottengo il messaggio "esocketerror ......... 1053"? |
|
|
|
|
|
#11 | |
|
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
Però bisognerebbe anche capire dove lo ottieni quel messaggio di errore (che credo sia 10053, non 1053). In generale ci sono gli eventi OnClientError/OnError, però potrebbe servirti anche qualche try/catch... |
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
Quote:
Codice:
for (int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++)
{
ServerSocket1->Socket->Connections[i]->SendText(String(i));
}
So che si poteva gestire attraverso try/catch ignorando l'errore nel senso di: Codice:
for (int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++)
{
try {
ServerSocket1->Socket->Connections[i]->SendText(String(i));
} catch(...) { } // ignora l'eccezione e continua
}
Ultima modifica di misterx : 18-10-2011 alle 16:27. |
|
|
|
|
|
|
#13 |
|
Member
Iscritto dal: May 2009
Messaggi: 186
|
Nel codice iniziale l'invio della stringa avveniva alla pressione di un pulsante. Se è ancora così, non dovresti avere alcun tipo di errore poichè la disconnessione del client (se effettuata correttamente) è gestita in automatico. Altrimenti spiega meglio come ottieni l'errore. try/catch in quella circostanza non serve.
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
Quote:
Il pulsante esegue(lancia) una funzione ed in luogo di un for() c'è un while() che continua ad invare dati all'infinito a chi si connette. Se il client si disconnette sia ha errore 10053. |
|
|
|
|
|
|
#15 |
|
Member
Iscritto dal: May 2009
Messaggi: 186
|
Dalla descrizione non mi sembra un granchè, ma senza vedere il codice aiutarti è piuttosto arduo.
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
rimedio subito
//client Codice:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
ClientSocket1->Port = 5000;
ClientSocket1->Host = "127.0.0.1";
ClientSocket1->Active = True;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
ClientSocket1->Active = False;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
ClientSocket1->Active = False;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
if( ClientSocket1->Active )
Edit1->Text = Socket->ReceiveText();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
if( ClientSocket1->Active )
Edit1->Text = ClientSocket1->Socket->ReceiveText();
server Codice:
bool bAbort;
void test(void);
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
ServerSocket1->Port = 5000;
ServerSocket1->Active = True;
bAbort = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
ServerSocket1->Active = False;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Socket->SendText(Edit1->Text);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
bAbort = false;
test();
}
//---------------------------------------------------------------------------
void test(void)
{
int i=0;
while(bAbort == false)
{
for(int actconn = 0; actconn < Form1->ServerSocket1->Socket->ActiveConnections; actconn++)
Form1->ServerSocket1->Socket->Connections[actconn]->SendText(String("connessione numero: ") + String(i++));
Application->ProcessMessages();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
bAbort = true;
}
//---------------------------------------------------------------------------
|
|
|
|
|
|
#17 |
|
Member
Iscritto dal: May 2009
Messaggi: 186
|
Vedo che gli errori già segnalati ci sono ancora, quindi non so quanto possa essere utile, ad ogni modo il problema dell'errore 10053 è che stai inviando continuamente una marea di dati verso i client, quindi è altamente probabile che la disconnessione avvenga durante uno di questi invii. L'evento OnClientError (che già ti avevo indicato) non è gestito e pertanto ti viene visualizzato l'errore. A parte quello, se stai facendo solo qualche prova veloce d'accordo, altrimenti ti suggerirei di rivedere bene tutto il codice e di pensare ad un'architettura migliore (leggasi: multithreading o timer, in base a cosa devi fare). |
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
sto ancora effettuando delle prove, gli errori verranno corretti dopo. Comunque non ho idea di come gestire l'evento che mi suggerisci, non ho molta esperienza con questa parte della programmazione.
Qua mi ci vuole il manuale del 6.0 Ultima modifica di misterx : 18-10-2011 alle 18:27. |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3741
|
ho scoperto come gestire l'evento OnClientError
Codice:
void __fastcall TForm1::ServerSocket1ClientError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
if (ErrorCode == 10053)
{
Socket->Close();
}
ErrorCode = 0;
}
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 14:29.




















