PDA

Visualizza la versione completa : [C++] Socket


DarthSandr
25-09-2008, 11:29
Salve a tutti, ho un'applicazione per palmari scritta in C++ (Visual Studio 2005) in cui in un ciclo infinito viene fatto un polling su un server per estrarre delle info da scrivere in un file.

La funzione che apre il Socket e' la seguente:




void getTicket(bool notify) {
int iResult;
WSADATA wsaData;

SOCKET ConnectSocket;
struct sockaddr_in clientService;

int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "91#3#AB456LP\n";
char recvbuf[DEFAULT_BUFLEN];

//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup failed with error: %d\n", iResult);
if (notify) ::MessageBox(NULL, _T("WSAStartup Failed"), _T("Info"), 0);
return;
}

//----------------------
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
if (notify) ::MessageBox(NULL, _T("Socket creation Failed"), _T("Info"), 0);
return;
}

//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
clientService.sin_family = AF_INET;
// clientService.sin_addr.s_addr = inet_addr( "163.162.93.154" );
clientService.sin_addr.s_addr = inet_addr( "163.162.91.29" );
clientService.sin_port = htons( 9999 );

//----------------------
// Connect to server.
iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
if (iResult == SOCKET_ERROR) {
printf( "connect failed with error: %d\n", WSAGetLastError() );
closesocket(ConnectSocket);
WSACleanup();
if (notify) ::MessageBox(NULL, _T("Connection Failed"), _T("Info"), 0);
return;
}

//----------------------
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send() failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
if (notify) ::MessageBox(NULL, _T("Data send Failed"), _T("Info"), 0);
return;
}

printf("Bytes Sent: %d\n", iResult);

// shutdown the connection since no more data will be sent
CTime currentTime = CTime::GetCurrentTime();
CTime expirationTime = currentTime;
expirationTime = expirationTime + CTimeSpan(10);
// Receive until the peer closes the connection
do {
currentTime = CTime::GetCurrentTime();
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
//VerifyErrors(1);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 ) {
//VerifyErrors(0);
printf("Connection closed\n");
}
else {
//VerifyErrors(0);
printf("recv failed with error: %d\n", WSAGetLastError());
}

} while (!( iResult > 0 ) && (currentTime < expirationTime));

// cleanup
closesocket(ConnectSocket);
WSACleanup();

if (iResult > 0) {
if ( recvbuf[0] == 'T') {
CString TicketStr = (CString)recvbuf;
createTicketFile(TicketStr);
if (notify) {
palmare_evt = TRUE;
reserv_flag = TRUE;
// ::MessageBox(NULL, _T("Ticket downloaded"), _T("Info"), 0);
}
if (!notify && !reservedTicketPresent) {
reservedTicketPresent = true;
// ::MessageBox(NULL, _T("Parking Ticket downloaded"), _T("Info"), 0);
}
}
else {
if (notify) {
::MessageBox(NULL, _T("No Reservation Found"), _T("Info"), 0);
}
else {
// cancello il Ticket prenotato
if (reservedTicketPresent) {
if (isTicketReserved()) {
deleteReservedTicket();
logFile = fopen( "\\Programmi\\Terminale Utente\\logFile.txt", "a" );
fprintf(logFile, "Cancello Ticket prenotato!");
fclose(logFile);
}
reservedTicketPresent = false;
// ::MessageBox(NULL, _T("Ticket deleted"), _T("Info"), 0);
}
}
}
}
else {
if (notify) ::MessageBox(NULL, _T("Connection Failed"), _T("Info"), 0);
}

}



Succede che se prima di avviare l'applicazione sul terminale la connessione in rete e' perfettamente funzionante tutto procede senza problemi.
Se la connessione non e' attiva ovviamente non funziona.
Se invece la connessione e' attiva e apro l'applicazione e tutto funziona ma, mentre il ciclo while infinito continua a fare il suo polling, io disabilito la connessione ovviamente non funziona ma se la riabilito (lasciando l'applicazione aperta) il Socket continua a non funzionare e per ripristinare il tutto devo chiudere l'applicazione e riaprirla.
Chiedo:
1) E' possibile in qualche modo testare che la connessione alla rete alla sia attiva prima di inviare il Socket? Esiste qualche metodo del C che possa fare questo?
2) Perche' se tiro giu' la connessione e poi la ripristino il Socket non funziona?

DarthSandr
25-09-2008, 12:24
E' possibile settare il timeout del metodo connect()? C'e' un metodo apposito? Sto cercando su google ma non sto trovando niente!

menphisx
25-09-2008, 19:01
Originariamente inviato da DarthSandr
E' possibile settare il timeout del metodo connect()? C'e' un metodo apposito? Sto cercando su google ma non sto trovando niente!

select, oppure poll.

:ciauz:

Loading