webForumDet fria alternativet

Socket Error

9 svar · 701 visningar · startad av Toonster

ToonsterMedlem sedan feb. 20001 546 inlägg
#1

Så här nu i semestertider så har jag tid att greja med mina "privata" projekt.

Har gjort ett program som hämtar information från en server på Internet. Nu är det bara den sista biten kvar (som alltid...) felhantering...

Den enda felhanterig som strular, är om det inte finns någon anslutning till nätverk/internet. Lyckas helt enkelt inte att fånga undantaget. Någon som har några tips?
Jag använder C++ Builder som ni kanske ser...

Redigerad kod.

TIdHTTP* httpanslutning = new TIdHTTP(this);
        if(httpanslutning){
            try
            {
                httpanslutning->Get("http://servernamnet/datapump");

            }
            catch(Exception &ex) { // funkar ej vid EIdSocketError 
                 ShowMessage("socket error");
            }
             catch(...){
                  ShowMessage("Okänt fel");
            }

Problemet: om httpanslutning->get() misslyckas pga. tex. nätverkskabeln är ur, så fångas detta inte upp av catch() avsnitten...

Har letat förgäves efter exempel som använder denna Indy komponent.

Som sagt, allt annat funkar perfekt...

PragmaMedlem sedan juni 200317 inlägg
#2

Uppkopplad mot nätet?

Det här är ett sätt av många.
Kolla om du har en aktiv uppkoppling mot nätet innan...
Använd min egna funktion IsConnect(...) nedan eller använd dig av Ms InternetGetConnectedState(...).

Länk till InternetGetConnectedState:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wininet/wininet/internetgetconnectedstate.asp

////////////
// main.cpp
////////////

/***********************************
 Author:	Åke Strandberg
 Date:	June 1, 2002
 Email:	[email]ake.programmer@swipnet.se[/email]
************************************/

////////////////////
// System inlcludes
////////////////////
#include<windows.h>
#ifndef _WINSOCKAPI_
#include <winsock2.h>// || <winsock.h>// WSAStartup, WSACleanup, gethostbyaddr, inet_addr
#endif
#pragma comment(lib, "ws2_32.lib")// || wsock32.lib
////////////////////
// System inlcludes
////////////////////

//////////////////////////////////////////////////////////////////////////////
// NOTE!!
// If you use one of these ip-addresses:		microsoft.com "207.46.230.218" or
//																					netscape.com  "" or ...
//
// a messagebox pops up if you are not connected to the internet.
//
// REGKEY == [HKEY_CURRENT_USER\Software\Microsoft\RAS Autodial\Addresses]
//
//
//////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////
// 63.229.91.35 == [url]www.programmersheaven.com[/url]
/////////////////////////////////////////////
#define MY_IP TEXT("63.229.91.35")

/////////////////////
// Prototype
/////////////////////
BOOL IsConnect(VOID);

/////////////////////////////////////////////////////////
// The WinMain function is called by the system as the 
// initial entry point for a Win32-based application. 
/////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPTSTR,int)
{
		if ( IsConnect() )
			MessageBox(0,"You are connected to the internet!","Message",\
			MB_ICONINFORMATION|MB_SYSTEMMODAL);
		else
			MessageBox(0,"You are not connected to the internet!",\
			"Message",MB_ICONWARNING|MB_SYSTEMMODAL|MB_ICONERROR);

		return 0;
}// < WinMain />

/*************************************************************

 Return true if there is an active connection to the internet.

**************************************************************/
BOOL IsConnect(VOID)
{
		hostent *hp =0; 
		unsigned int addr=0; 
		WSADATA wsaData; 
		memset(&wsaData,0,sizeof(wsaData));
		int iRetVal=0;

		///////////////////////////////////////
		// Initialize with the WINSOCK library   
		///////////////////////////////////////
		iRetVal = WSAStartup ( 0x0202, &wsaData);

		if (iRetVal)
		{ 
		  // WSAStartup failed
			WSACleanup () ; 
			return FALSE ; 
		} 
		
		//////////////////////////////////////
		// Convert ip-address to a usable one 
		//////////////////////////////////////
		addr = inet_addr(MY_IP) ; 

		//////////////////////////////////
		// Retrieves the host information
		//////////////////////////////////
		hp = gethostbyaddr( ( char *) &addr, 4, AF_INET) ;

		if(!hp)
		{
		  WSACleanup ();
			return FALSE;
		}
		
		////////////
		// Clean up
		////////////
		WSACleanup () ; 

		//////////////////////
		// Active connection
		//////////////////////
		return TRUE;

}// < IsConnect />

:i

ToonsterMedlem sedan feb. 20001 546 inlägg
#3

Njae, jag vill helst bara fånga undantaget, direkt från TIdHTTP komponenten, utan att använda ytterligare kod. Men tack ändå, i värsta fall får jag väl använda några Windows API'er...

PeWMedlem sedan juni 20006 839 inlägg
#4

Kollade lite på nätet efter TIdHTTP och är det inte med TIdTCPConnection som anslutningen ska skapas?

http://www.atari-source.com/docs/indy/9.0/html/011438.html

ToonsterMedlem sedan feb. 20001 546 inlägg
#5

Jo, TIdHTTP är en subklass till TIdTCPConnection.

Alltså, allt fungerar klockrent. Det är bara EIdSocketError som jag vill fånga för att kunna visa en meddelanderuta.

PeWMedlem sedan juni 20006 839 inlägg
#6

Provat med EIdException istället för Exception?

ToonsterMedlem sedan feb. 20001 546 inlägg
#7

Japp, provat alla exceptions jag hittat...

nikoMedlem sedan juni 20022 415 inlägg
#8

Nu har jag inget erfarenhet av Borland-miljöer eller komponenten du använder, men det låter ju väldigt konstigt att felet skulle kunna trilla rakt igenom den generella felhanteraren:

catch(Exception &ex)

??

Men om du är desperat och enda syftet är att hindra att applikationen krashar i onödan så borde det gå att temporärt ta över Windows egna hantering av ohanterade fel med SetUnhandledExceptionFilter. Kanske lite over-kill men om det inte går att lösa på annat sätt så ..

ToonsterMedlem sedan feb. 20001 546 inlägg
#9

Ja, den borde fångas i den generella händelsehanteraren, konstigt... Jag ska labba vidare, för det är ganska viktigt att kunna presentera en egen meddelanderuta istället för en programfelsruta. Jag kan ju stänga av vissa exceptions, men då blir det som sagt ingen meddelanderuta... Kanske överväger en annan komponent för HTTP hanteringen...

ToonsterMedlem sedan feb. 20001 546 inlägg
#10

Ville bara meddela att det har löst sig. När jag gjorde inställningarna för att slutföra programmet, dvs. ta bort debugg läget och kompilera ingående komponenter statiskt, så fångades händelsen upp. (på gränsen till ett amatörfel...)

Jag borde ha testat detta tidigare, men tyvärr, jag är van att använda debuggläget påslaget tills programet är färdigt för "leverans"...

Tack ändå för era tips!
Pragma -> Din kod kommer jag kanske att få användning av i framtiden, den är sparad i min "program bank"...

129 ms totalt · 3 externa anrop · cache AV · v20260731051352-full.56cc9887
0 ms — hämta statistik (cache)
0 ms — hämta forumlista (cache)
127 ms — hämta tråd, inlägg och bilagor (db)