|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Apr 2009
Messaggi: 83
|
GUI client
Salve,
Mi scuso se inizio un argomento già trattato ma ho cercato un po' e non sono riuscito a trovare nulla..magari reindirizzatemi voi. Allora, non devo scusarmi per l'inglese stavolta ma per la poca conoscenza si. Sto lavorando alla tesi e mi serve una GUI che faccia da client per un'applicazione (di cui so che lavora da server con protocollo TCP/IPv4). L'applicazione in questione è la finestra di simulazione interattiva di OpenModelica (conoscete?).. Vabbè in pratica ho creato una GUI (WxDev ed anche la MFC di VisualStudio ma sempre utilizzando i winsock.h, e quindo lo stesso codice )con vari buttons, ognuno con un messaggio pre impostato da inviare al server. Riesce a connettersi a ad inviare il messaggio. Il problema è che lo fa solo al primo click. Funziona anche se ad un pulsante associo più send() ma gli altri invii che provo a fare non li vede neppure. Premetto che prima di ieri non avevo mai creato un client e che non sono espertissimo di programmazione in generale ma mi tocca farlo... Avrò quindi sicuramente fatto qualche castroneria tipo: -Ho copiato lo stesso codice per ogni button (non so se questo crea problemi). -Non so se devo necessariamente prendere la risposta del server (so che la manda su una porta differente). Cmq vi posto il codice e faccio prima... Codice:
void Project1Frm::WxButton1Click(wxCommandEvent& event)
{
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);
SOCKET sock;
sock=socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(port);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr));
wxString mess;
mess="start#1#end";
send(sock,mess,strlen(mess),0);
}
/*
* WxButton2Click
*/
void Project1Frm::WxButton2Click(wxCommandEvent& event)
{
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);
SOCKET sock;
SOCKADDR_IN addr;
short port;
port = 10501;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(port);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr));
wxString mess;
mess="stop#2#end";;
send(sock,mess,strlen(mess),0);
}
So che manca la chiusura del socket e il rilascio delle librerie ma avevo pensato di farli in un altro button. Grazie mille per l'attenzione Francesco |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
ciao,
se non mi sbaglio hai sistemato l'iniziazione del socket nella routine agganciata all'evento click del bottone "send". Ti consiglio di spostare il codice per l'iniziazione del socket in una routine a parte.... che verrà eseguita una volta! Il tasto eseguirà solo la send(). |
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Apr 2009
Messaggi: 83
|
Scusa l'ignoranza, ma dove lo piazzo? Ci avevo pensato e lo avevo messo nella routine di creazione della finestra in modo che si connettesse appena avviata ma poi mi servivano il socket per la send..come faccio a renderlo pubblico?
|
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Apr 2009
Messaggi: 83
|
OK...forse ho risolto..grazie mille..ho dichiarato sock tra i private in progettoFrm.h
Pare funzioni..vi faccio sapere tra un po'.. Ah..non mi abbandonate perche avrò ancora bisogno di voi |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
ad esempio nel costruttore che provvederà a recuperare gli argomenti dalla GUI.
|
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Apr 2009
Messaggi: 83
|
ehm..si..credo di aver fatto proprio questo..
..Ora funziona..grazie della dritta.. Ho un'altra domanda.. Posso inizializzare più socket?..praticamente so che il server riceve dalla porta 10501 e risponde su 10500 e 10502 a seconda del tipo di risposta diciamo.. Se per esempio eseguo tre connect() con le tre diverse porte dovrebbe funzionare?..ovviamente lo chiedo perchè a me non va..o mi si blocca o semplicemente non riceve nulla.. Dalla finestra del server ottengo un "Fail to send"..può dipendere dalla dimensioni discordi delle stringhe inviate rispetto a quelle pronte a ricevere? |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Si, si può inizializzare più socket.
Il problema semmai è sul lato server... Se hai dei problemi con la send() magari posta il codice.... la dimensione dei buffer non creano problemi. La cosa fondamentale è essere sicuri di aver letto tutto ciò che c'era da leggere. Quindi devi impostare un ciclo su recv() in modo corretto. Con C++ è abbastanza semplice... Questo l'avevo fatto in C ma rende l'idea: Codice:
// Loop per la gestione dei dati ricevuti e scrittura su disco:
while(1)
{
memset(buffer, 0, MAX);
err = WSARecv(sock, &DataBuf, 1, &lpNumberOfBytesRecvd, &lpFlags, &RecvOverLapped, 0);
if(err == -1) { mngmt_sock_error(); break; }
else TotalBytesRecvd += lpNumberOfBytesRecvd;
if(crypto_flag==1) decrypt(); // Se la connessione è crittografata devo decodificare
if(videout) cout << buffer;
if(recv_data(buffer, fplog) == -1) cerr << "Non scritto: " << buffer << endl;
}
http://msdn.microsoft.com/en-us/libr...88(VS.85).aspx |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
l'esempio che ti ho messo è in C. Sono uno zuccone
, prova questo qui:http://msdn.microsoft.com/en-us/libr...ts.socket.aspx |
|
|
|
|
|
#9 |
|
Member
Iscritto dal: Apr 2009
Messaggi: 83
|
a
Ultima modifica di fdf86 : 29-07-2010 alle 14:32. |
|
|
|
|
|
#10 | |
|
Member
Iscritto dal: Apr 2009
Messaggi: 83
|
Scusa la risposta tarda..ma non ho avuto proprio tempo..
Allora..ho chiesto nel forum del programma "server" ma ancora nessuna risposta. Ti posto il codice..il progetto si chiama GUIs GUIsFrm.h Codice:
private:
//Do not add custom control declarations between
//GUI Control Declaration Start and GUI Control Declaration End.
//wxDev-C++ will remove them. Add custom code after the block.
////GUI Control Declaration Start
wxTextCtrl *WxMemo1;
wxStaticText *WxStaticText6;
wxStaticText *WxStaticText5;
wxStaticText *WxStaticText4;
wxStaticText *WxStaticText3;
wxStaticText *WxStaticText2;
wxStaticText *WxStaticText1;
wxSlider *WxSlider2;
wxSlider *WxSlider1;
wxButton *WxButton5;
wxButton *WxButton4;
wxButton *WxButton3;
wxButton *WxButton2;
wxButton *WxButton1;
////GUI Control Declaration End
SOCKET sock;
SOCKET sockIn;
SOCKET sockRes;
SOCKADDR_IN addr;
SOCKADDR_IN addr2;
SOCKADDR_IN addr3;
char buf[100];
int n;
wxString mess;
int fl;
GUIsFrm.cpp Codice:
.........
........
void GUIsFrm::WxButton1Click(wxCommandEvent& event)
{
WxMemo1->Clear();
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);
sock=socket(AF_INET, SOCK_STREAM, 0);
crea_addr(&addr,10501,"127.0.0.1");
connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr));
mess="setcontrolclienturl#1#127.0.0.1#10500#end";
send(sock,mess,strlen(mess),0);
//se mi metto ad aspettare qua una risposta il programma si blocca
mess="settransferclienturl#2#127.0.0.1#10502#end";
send(sock,mess,strlen(mess),0);
//come sopra
// ora inizializzo gli altri socket
sockIn=socket(AF_INET, SOCK_STREAM, 0);
crea_addr(&addr2,10500,"127.0.0.1");
if(connect(sockIn, (struct sockaddr*)&addr2, sizeof(struct sockaddr))==0)
(*WxMemo1)<<"10500 connesso\n";
else
(*WxMemo1)<<"10500 non connesso\n Error "<<WSAGetLastError()<<"\n";
sockRes=socket(AF_INET, SOCK_STREAM, 0);
crea_addr(&addr3,10502,"127.0.0.1");
if(connect(sockRes, (struct sockaddr*)&addr3, sizeof(struct sockaddr))==0)
(*WxMemo1)<<"10502 connesso\n";
else
(*WxMemo1)<<"10502 non connesso\n Error "<<WSAGetLastError()<<"\n";
}
/*
* WxButton2Click
*/
void GUIsFrm::WxButton2Click(wxCommandEvent& event)
{
wxString mess;
mess="setfilter#3#asc:ord#val#end";
send(sock,mess,strlen(mess),0);
int n;
n=recv(sockIn,buf,sizeof(buf),0);
//mess[n]=0;
(*WxMemo1)<<buf<<"\n";
mess="start#4#end";
send(sock,mess,strlen(mess),0);
n=recv(sockIn,buf,sizeof(buf),0);
//mess[n]=0;
(*WxMemo1)<<buf<<"\n";
// insert your code here
}
/*
* WxButton3Click
*/
void GUIsFrm::WxButton3Click(wxCommandEvent& event)
{
wxString mess;
mess="pause#5#end";
send(sock,mess,strlen(mess),0);
// insert your code here
}
/*
* WxButton4Click
*/
void GUIsFrm::WxButton4Click(wxCommandEvent& event)
{
mess="stop#6#end";
send(sock,mess,strlen(mess),0);
// insert your code here
}
/*
* WxButton5Click
*/
void GUIsFrm::WxButton5Click(wxCommandEvent& event)
{
mess="shutdown#7#end";
send(sock,mess,strlen(mess),0);
closesocket(sock); // chiudo la socket
closesocket(sockIn);
closesocket(sockRes);
WSACleanup();
// insert your code here
}
//void crea_addr(struct sockaddr_in*,int , char*);
void crea_addr(struct sockaddr_in* addr,int port, char* server)
{
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr(server);
addr->sin_port = htons(port);
}
/*
* GUIsFrmActivate
*/
void GUIsFrm::GUIsFrmActivate(wxActivateEvent& event)
{
// insert your code here
}
/*
* WxSlider1Scroll
*/
void GUIsFrm::WxSlider1Scroll(wxScrollEvent& event)
{
int slid = WxSlider1->GetValue();
snprintf(buf,100,"changevalue#%d#60.0#val=%d#end",fl,slid);
fl++;
send(sock,buf,strlen(buf),0);
buf[0]=0;
n=recv(sockIn,buf,sizeof(buf),0);
//buf[n]=0;
(*WxMemo1)<<buf<<n<<"\n";
;
// insert your code here
}
/*
* WxSlider2Scroll
*/
void GUIsFrm::WxSlider2Scroll(wxScrollEvent& event)
{
// insert your code here
}
Ho appena verificato che alla connect degli altri socket mi viene restituito errore 10061..ovvero Quote:
Pensi che debba riscrivere il tutto seguendo il tuo link o che sia un problema del server? La connessione che ho creato non può inviare e ricevere contemporaneamente, giusto?. Grazie e perdonami ancora se ho risposto così tardi |
|
|
|
|
|
|
#11 |
|
Member
Iscritto dal: Apr 2009
Messaggi: 83
|
HO RISOLTO
Praticamente l'altra applicazione non invia risposte come server ma come client..mi è venuto in mente leggendo la scritta "fail to send" e per l'errore 10061..ho quindi creato anche un server nella GUI che ascolta le risposte del programma esterno.. Grazie mille! Saluti Francesco. P.S.:se dovessi aver bisogno di ulteriori info sull'argomento posso scrivere qua o devo creare una nuova discussione? |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Bene.
Secondo me se gli altri post riguardano la stessa applicazzione puoi continuare questo thread, ma normalmente si riapre un'altra discussione.... in questo modo chi fa delle ricerche nel forum in cerca di soluzioni ha risultati più coerenti. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 01:58.












..
, prova questo qui:








