PDA

Visualizza versione completa : Controllo SOCKET C


NS-1
03-05-2004, 17.32.52
ciao,

ho creato un client e un server in C e desidero monitorare ogni 10 secondi o manualmente se le connessioni stabilite sono ancora attive...

potete aiutarmi?

grazie
Ns-1

P8257 WebMaster
03-05-2004, 17.38.01
In ANSI-C l'hai scritto?

Bye :cool:

NS-1
03-05-2004, 17.54.47
si...

:)

P8257 WebMaster
03-05-2004, 18.01.50
Sar probabilmente criticato per questa scelta, soprattutto a livello di "analisi" ma io ritengo che occorra considerare una cosa:

La soluzione migliore (a mio avviso) per avere un "qualcosa" che possa controllare ciclicamente o ad un dato evento, un thread.
In questo caso, dato che ti interessa controllare lo stato della connessione, sarebbe utile creare un thread demone che lo faccia...

Fare un thread in C puro, per fare un semplice controllo, mi sembra troppo e tutti sappiamo che il linguaggio che opera meglio coi thread e dove fare un thread al quanto semplice Java, personalmente creerei una classe thread java che si interfaccia via JNI al tuo componente C, chiamando periodicamente una subroutine ove tu controlli lo stato della connessione e fornisci indietro i dati direttamente a Java.

Bye :cool:

NS-1
03-05-2004, 18.15.47
io pensavo di fare semplicemente una funzione in C con un timeout...

es.

quando invio i miei dati o premo un tasto "REFRESH"
richiamo la mia funzione che:
invia pacchetto "pippo"
se non ho risposta entro 'TIMEOUT' concludo la connessione ed eventualmente la ristabilisco...

cos male come soluzione?

ps - esiste una funzione SLEEP?

grazie

Ns-1

P8257 WebMaster
03-05-2004, 18.34.29
Scusa, avevo capito forse male il tuo post...
La soluzione mi sembra idonea, in C esiste la funzione sleep() che acceta come parametri il numero di secondi in cui vuoi fare restare in attesa il processo... (ci sono tuttavia altri metodi pi soffisticati per fare lo 'sleep')

La soluzione valida, secondo me.

Bye :cool:

NS-1
03-05-2004, 18.41.47
:D .. grazie...

cosa intendi per metodi pi sofisticati? :D

P8257 WebMaster
04-05-2004, 09.11.03
Per Soluzione pi soffisticata intendo appunto un thread, un daemon o comunque un componente chiamante scritto "ad hoc"... o magari un listener al posto dello sleep e cos via.

Bye :cool:

NS-1
04-05-2004, 12.07.07
ok...

grazie...


:D

NS-1
06-05-2004, 18.55.19
ho quasi finito...

sorgenti di prog fatti bene con tutti i controlli del caso?

ciao

:D

NS-1
07-05-2004, 14.30.47
.. facendo i test ho notato che la prima volta che chiudo la connessione e lascio attivo il server va tutto bene, se stabilisco un'altra connessione e la chiudo ancora, il server riceve una stringa tipo: [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[

cosa non pulisco? cosa c' che non va?

grazie

Ns-1

P8257 WebMaster
07-05-2004, 14.47.54
Sicuramente ci sar qualcosa di "sporco", dipende dal codice, fai delle malloc? .. usi dei vettori?.. hai controllato gli indici?... stringhe senza terminatore ?....

Bye :cool:

pholcus
07-05-2004, 15.06.31
Potresti postare il codice?

Cmnq un'ottimo libro sui socket ( sotto linux ) e' Unix Network Programming di Richard Stevens..
Ti consiglio l'acquisto, anche se costa abbastanza..

Ciao

NS-1
07-05-2004, 15.17.45
web, 'malloc' non l'ho usato ma per il resto il codice ok, non sono un mago della programmazione ma in c me la cavo abbastanza...

secondo te, per esperienza magari, cosa potrebbe essere?

i caratteri non sono [[[[[[ ma ddddddddd

NS-1
07-05-2004, 15.18.49
non far caso a cosa uscito... il carattere giusto nella mappa caratteri : arial U+2560

P8257 WebMaster
07-05-2004, 16.21.39
NS-1 ha scritto:
web, 'malloc' non l'ho usato ma per il resto il codice ok, non sono un mago della programmazione ma in c me la cavo abbastanza...

secondo te, per esperienza magari, cosa potrebbe essere?

i caratteri non sono [[[[[[ ma ddddddddd

Nessuno mette in dubbio le tue capacit, sono cose che capitano.. senza codice comunque difficile capire ... io penso che sia qualcosa che non pulisci, qualche buffer, qualcosa che rimane nel socket al momento della riconnessione... difficile da dire, mi sono "incartato" moltissime volte in queste cose, per poi scoprire che erano banalit o sviste...

Bye :cool:

P.S.: A mio avviso il carattere restituito non ha alcuna importanza, quello che personalmente definisco come "schifezza" :D

NS-1
07-05-2004, 16.52.39
... ma sai che questa svista proprio non la vedo e ci sto perdendo i capelli? :mad:

P8257 WebMaster
07-05-2004, 17.03.38
NS-1 ha scritto:
... ma sai che questa svista proprio non la vedo e ci sto perdendo i capelli? :mad:

Tipico .. :D .. altrimenti non sarebbe una svista..

Usa il debugger !

Bye :cool:

NS-1
07-05-2004, 20.44.28
:D

se non ci riesco, poster il codice


grazie

NS-1
09-05-2004, 23.03.11
sorgenti di prog fatti bene con tutti i controlli del caso?

pholcus
09-05-2004, 23.14.35
Ne ho sicuramente da qualche parte, ma sono per linux/unix..

NS-1
10-05-2004, 14.26.21
vanno bene cmq... devo solo comprendere "la logica" e cosa sbaglio nel disconnettere e riconnettere...

grazie...


:p

NS-1
10-05-2004, 14.32.24
..questo il mio server:

#include <stdio.h>
#include <winsock.h>
#include <vector>
#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;


int PORT = 1978;
int MAX_CONNECT = 10;
bool bVal = true;


struct CLIENT_TYP {
bool InUse;
SOCKET ClientSocket;
struct sockaddr_in ClientAddr;
};


SOCKET lstSocket;
struct sockaddr_in saServer;

vector<CLIENT_TYP> Client;

int ClientsConnected = 0;
timeval timeout;

bool bLog = true;
bool bLogError = true;

////////////////////////////////////////////////////////

bool Error(char *error)
{
if (bLogError)
printf(error);
return true;
}

bool Log(char *log)
{
if (bLog)
printf(log);
return true;
}

////////////////////////////////////////////////////////

bool Setup()
{
int nRet;
WSADATA wsaData;

saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = INADDR_ANY;
saServer.sin_port = htons(PORT);

Log("\nInitializing Winsock...");
if (WSAStartup(MAKEWORD(1,1), &wsaData)) {
Log("FAILED\n");
Error("Error Initializing Winsock\n");
WSACleanup();
return false;
}
Log("OK\n");

Log("Creating Socket...");
lstSocket = socket(AF_INET, SOCK_STREAM, 0);
if (lstSocket == INVALID_SOCKET) {
Log("FAILED\n");
Error("Error Creating Socket\n");
WSACleanup();
return false;
}
Log("OK\n");

Log("Binding Socket...");
nRet = bind(lstSocket, (LPSOCKADDR)&saServer, sizeof(struct sockaddr));
if (nRet == SOCKET_ERROR) {
Log("FAILED\n");
Error("Error Binding Socket\n");
WSACleanup();
return false;
}
Log("OK\n");

Log("Setting up Listening...");
nRet = listen(lstSocket, SOMAXCONN);
if (nRet == SOCKET_ERROR) {
Log("FAILED\n");
Error("Error Listening\n");
WSACleanup();
return false;
}
Log("OK\n");

if (!Client.empty())
Client.clear();

Log("\n[ Server Set Up Successfull ]\n");
return true;
}

////////////////////////////////////////////////////////

int Disconnect(int Index)
{
closesocket(Client[Index].ClientSocket);
Client[Index].InUse = false;
ClientsConnected--;

return 1;
}

void Shutdown()
{
shutdown(lstSocket, 2);
for (int i = 0; i < Client.size(); i++)
Disconnect(i);
WSACleanup();
Log("[ Server Shut Down ]\n\n");
}

////////////////////////////////////////////////////////

int Check_Connections()
{
int nRet;
fd_set readfds;
int Client_Length;
CLIENT_TYP tmpClient;
Client_Length = sizeof(tmpClient.ClientAddr);

timeout.tv_sec = 0;
timeout.tv_usec = 0;

if (ClientsConnected < MAX_CONNECT)
{
FD_ZERO(&readfds);
FD_SET(lstSocket, &readfds);

nRet = select(lstSocket + 1, &readfds, NULL, NULL, &timeout);
if (nRet > 0) {
int clIndex = Client.size();
CLIENT_TYP newClient;
Client.push_back(newClient);

Client[clIndex].ClientSocket = accept(lstSocket, (struct sockaddr*)&Client[clIndex].ClientAddr, &Client_Length);
if (Client[clIndex].ClientSocket == INVALID_SOCKET) {
Log("\nAttempt to accept incoming connection failed");
return 1;
}
char *ClientIp = inet_ntoa(Client[clIndex].ClientAddr.sin_addr);
Log("\nNew connection made with: ");
Log(ClientIp);
Log("\n\n");
ClientsConnected++;
Client[clIndex].InUse = true;
}
}
return 1;
}

////////////////////////////////////////////////////////

void Get_Message(int clIndex)
{
int nRet;
char data[1000];

nRet = recv(Client[clIndex].ClientSocket, data, sizeof(data), 0);
char *ClientIp = inet_ntoa(Client[clIndex].ClientAddr.sin_addr);

if (nRet == 0) {
Log("\nClient has disconnected: "), Log(ClientIp), Log("\n");
Disconnect(clIndex);
}
else {

Log("<"), Log(ClientIp), Log("> ");
data[nRet] = '\0';

cout << data;


if(data[0] == '$' || data[0] == '+'){

shutdown(lstSocket, 0); // no ricezione
Disconnect(clIndex);

if(data[0] == '$')
WSACleanup();

Log("\n\nConnessione chiusa da: "), Log(ClientIp), Log("\n\n");


bVal = false;
}

else{
int index;

for(index = 0; index <= 999; index++){
if(data[index] == '\0'){

char buf2[10] = " --> OK\0";
char *bufPTR;

bufPTR = &data[index];

*strcat(bufPTR, buf2);

index = 1000;
}
}

send(Client[clIndex].ClientSocket, data,sizeof(data), 0);

Log("\n");

}

}
}

////////////////////////////////////////////////////////

void Check_Message()
{
int nRet;
fd_set msg_fds;
fd_set err_fds;
int nfds;

timeout.tv_sec = 0;
timeout.tv_usec = 0;

FD_ZERO(&msg_fds);
FD_ZERO(&err_fds);
nfds = 0;

for(int i = 0; i < Client.size();) {
FD_SET(Client[i].ClientSocket, &msg_fds);
FD_SET(Client[i].ClientSocket, &err_fds);
nfds++;
i++;
}

nRet = select(nfds, &msg_fds, NULL, &err_fds, &timeout);

if (nRet > 0) {
for(int i = 0; i < Client.size(); i++) {

if (FD_ISSET(Client[i].ClientSocket, &err_fds)) {

char *ClientIp = inet_ntoa(Client[i].ClientAddr.sin_addr);
Log("\nClient has disconnected: "), Log(ClientIp), Log("\n");
Disconnect(i);
}

if (FD_ISSET(Client[i].ClientSocket, &msg_fds)) {
Get_Message(i);

}

}
}

}

////////////////////////////////////////////////////////

void main()
{

Setup();

while (bVal) {

Check_Connections();

Check_Message();

}

Shutdown();

system("PAUSE");
}


se non trovate errori poster anche il client...

grazie
Ciao

NS-1
10-05-2004, 18.44.29
... fatto prove?

:rolleyes:

P8257 WebMaster
10-05-2004, 18.55.55
Per quel che riguarda me .. l'ho letto .. stasera o domani mattina lo provo ;)

Bye :cool:

NS-1
10-05-2004, 19.38.26
..grazie... :)

NS-1
12-05-2004, 14.03.38
... provato? :p

NS-1
13-05-2004, 17.56.39
?

LoryOne
13-05-2004, 18.42.23
Me lo sono copiato e compilato poco fa.
Mi faresti la cortesia di postare anche il client, per favore ?

NS-1
13-05-2004, 19.41.06
client:


#include <windows.h>

#include <sys/types.h>
#include <winsock.h>
#include <stdio.h>
#include <string.h>

#define PROTOPORT 1978
extern int errno;
char localhost[] = "localhost";

void main(argc, argv)
int argc;
char *argv[];
{
struct hostent *ptrh;
struct protoent *ptrp;
struct sockaddr_in sad;
int sd;
int port;
char *host;
int n=0;
char buf[1000];
char cDaInv=0;

#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif
memset((char *)&sad,0,sizeof(sad));
sad.sin_family = AF_INET;


if (argc > 2) {
port = atoi(argv[2]);
} else {
port = PROTOPORT;
}
if (port > 0)
sad.sin_port = htons((u_short)port);
else {
fprintf(stderr,"Bad Port Number %s\n",argv[2]);
exit(1);
}



if (argc > 1) {
host = argv[1];
} else {
host = localhost;
}



ptrh = gethostbyname(host);
if ( ((char *)ptrh) == NULL ) {
fprintf(stderr,"Invalid Host: %s\n", host);
exit(1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);



if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "Cannot map \"tcp\" to protocol number");
exit(1);
}


sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0) {
fprintf(stderr, "Socket Creation Failed\n");
exit(1);
}



if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"Connect Failed\n");
exit(1);
}




printf("\n\n DCN-Server\n\t+ Termina questo programma\n\t$ Termina anche il client\n\n - Connessione Stabilita\n");
//ECHO



do{

printf("\nINVIA: ");
gets(buf);

if(buf[0] != '+'){

send(sd,buf,strlen(buf),0);
n = recv(sd, buf, sizeof(buf), 0);
printf("%s\n",buf);
}
else
n = 0;


}while (n > 0);

closesocket(sd);

printf("\nConnessione Conclusa, Client %s\n\n", buf[0] == '+' ? "ancora attivo" : "disattivato");


system("PAUSE");
exit(0);
}

LoryOne
14-05-2004, 08.24.44
A me sembra tutto OK.

1-Ho lanciato il server
Risultato:

Initializing Winsock...OK
Creating Socket...OK
Binding Socket...OK
Setting up Listening...OK

[ Server Set Up Successfull ]

Il Server resta in attesa di ricevere messaggi dal client sulla porta predefinita.

2- Ho lanciato il client
Risultato:

DCN-Server
+ Termina questo programma
$ Termina anche il client

- Connessione Stabilita

INVIA:

3-Ho inviato un messaggio al Server: Io mi chiamo LoryOne

Risultato:

...
....
.....
New connection made with: 127.0.0.1

<127.0.0.1> Io mi chiamo LoryOne

4-Ho inviato un ulteriore messaggio.
Ok.

5-Ho chiuso il client (+) e Server in attesa
Ok.

6-Ho lanciato il client e ripetuto i punti 3-4
Ok.

7-Ho chiuso Server e Client ($)
Ok

Quale il problema ? :rolleyes:

LoryOne
14-05-2004, 08.37.48
Prova #2
1- Ho lanciato il server
Ok
2- Ho lanciato il client
Ok
3- Ho spedito qualcosa al server
Ok
4- Ho chiuso il client
5- Ho lanciato il client
Ok
6- Ho spedito al server
Ok
7- Ho chiuso entrambi
OK OK OK

LoryOne
14-05-2004, 08.49.21
Prova a lancaiare i due files compilati.
Se riscontri gli stessi errori, allora prova a vedere se esiste una patch per winsock.dll
Sul 98SE funziona.

NS-1
14-05-2004, 13.30.34
ciao,
intanto grazie per queste prove...

io faccio questo:

attivo il server
attivo il client
invio messaggio
disconnetto lasciando in ascolto il server
mi riconnetto
invio messaggio
chiudo connessione lasciando aperto il server

e dalla parte del server vengono visualizzati un centinaio di caratteri

...puoi fare anche tu questa prova?

grazie

Ns-1

NS-1
14-05-2004, 13.35.08
scusami, ho sbagliato...

la seconda volta che ti connetti,
invia messaggio
invia messaggio
e chiudi tutto con "$"


ok?

NS-1
14-05-2004, 13.41.19
...sai che i tuoi compilati funzionano?

che IDE/compilatore/linker usi?


:D

LoryOne
14-05-2004, 14.03.18
Ho compilato con DEV-C++

NS-1
14-05-2004, 14.14.38
..appena posso provo.... :D

grazie...


p.s. se funziona piuttosto bizzarro tutto ci... :rolleyes:

NS-1
17-05-2004, 09.21.41
ho installato un service pack.... tanto per cambiare... :D

vediamo se funziona ora.....

(F) (F) (F) :inn: (F) (F) (F)

NS-1
20-05-2004, 10.36.36
funziona tutto adesso... :mad:

fareste qualche modifica?
c' qualcosa che mi scappato?
avete suggerimenti?

sono un novellino nella programmazione di rete, quindi ogni consiglio gradito... :D

grazie

Ns-1

NS-1
21-05-2004, 10.42.01
LoryOne? P8257? pippo? pluto?















UE (W) LU ...cosa sar?
:D

NS-1
30-05-2004, 12.57.50
fareste qualche modifica?
c' qualcosa che mi scappato?
avete suggerimenti?

sono un novellino nella programmazione di rete, quindi ogni consiglio gradito...

grazie

Ns-1