PDA

View Full Version : HTTP Request senden



NEich
02-03-06, 09:32
Hallo *ALL,

ich habe folgende Aufgabe: Absetzen eines HTTP Requests von der iSeries und Empfangen der Antwort. Sollte eigentlich eine leichte Aufgabe sein. (Eine Art Webservice light)

Mit Java funktioniert das ohne weitere Probleme (eingebunden per JNI in ILE PRG), jedoch ist die Laufzeit inakzeptabel.

Da habe ich mich nach einer anderen Lösung umgeschaut und bin auf zwei Lösungsansätze gekommen:
- Die HTTPAPI von Scott Klement
- Einen HTTPClient in C
- SRVPGM iSockets von Bob Cozzi
Alle drei Lösungen benutzen auf der iSeries die gleichen C Funktionen um ein Socket aufzubauen und den Request zu senden.

Der C-Client ist auf einem Windows PC lauffähig (erfolgreich getestet), auf der iSeries bekomme ich jedoch bei allen drei Lösungen jeweils keine Antwort vom Webserver, bis die Connections auf einen Timeout laufen. Lt. Netstat werden die Bytes gesendet, aber keine Empfangen. Im Aufrufstapel ist ersichtlich, dass das Programm dann jeweils auf recv steht.

Sind evtl. TCPIP Einstellungen auf unserer iSeries falsch? Hat dort schon jemand ähnliche Erfahrungen gemacht, oder hat sogar vielleicht eine einfache andere Lösung?

Hier ist z.B. der C-Source:


#include <stdio.h>
#include <errno.h>

#ifdef _WIN32
/* Headerfiles für Windows */
#include <winsock.h>
#include <io.h>
#else
/* Headerfiles für Unix/Linux */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define closesocket(s) close(s)
#endif

/* Definitionen */
#define HTTP_PORT 80
#define HOST "99.33.137.29"
#define URL "/ERPDocumentMaster.do?part=K.04753.370.00.00"

/*==============*/
/* MAIN */
/*==============*/
int main( int argc, char **argv){
struct sockaddr_in server;
struct hostent *host_info;
unsigned long addr;
int sock;
char buffer[1024];
int count, bytes_sent;

/* Anpassung für Windows */
#ifdef _WIN32
short wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD (1, 1);
if (WSAStartup (wVersionRequested, &wsaData) != 0) {
fprintf( stderr, "Failed to init windows sockets\n");
exit(1);
}
#endif

/* Socket erstellen */
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
perror( "failed to create socket");
exit(1);
}


/* Server Verbindung definieren (Typ, IP Adresse und Portnummer) */
memset( &server, 0, sizeof (server));

server.sin_family = AF_INET;
server.sin_port = htons (HTTP_PORT);
server.sin_addr.s_addr = inet_addr (HOST);

/* Hostnamen auflösen */
if (server.sin_addr.s_addr == INADDR_NONE) {

host_info = gethostbyname (HOST);
if (host_info == NULL) {
fprintf( stderr, "unknown server: %s\n", HOST);
exit(1);
}
memcpy((char*) &server.sin_addr.s_addr,
host_info->h_addr,
host_info->h_length);
}

/* Zum Server verbinden */
if ( connect( sock, (struct sockaddr*)&server, sizeof( server)) < 0) {
perror( "can't connect to server");
exit(1);
}

/* HTTP Request senden */
sprintf( buffer,"GET %s HTTP/1.0\r\n\r\n",URL);
fprintf(stderr, buffer);
bytes_sent = send( sock, buffer, strlen( buffer), 0);
fprintf(stderr, "Bytes gesendet: %i", bytes_sent);

/* Antwort des Servers ausgeben */
if (bytes_sent > 0) {
while ((count = recv (sock, buffer, sizeof(buffer), 0)) > 0) {
write( 1, buffer, count);
}
}

/* Socket schließen */
closesocket( sock);
return count;
}</netdb.h></netinet></sys></sys></io.h></winsock.h></errno.h></stdio.h>

Rincewind
02-03-06, 10:00
Eventuell laufen schon andere Programme über die entsprechenden Ports ?

Sind die Ports bei dem PC Server entsprechend eingestellt ?

Hängt eine Firewall zwischen der Iseries und dem PC Server ?

(Das waren die 3 Hindernisse meines Client-Server Gerumpels)

Gruß
Rince

P.s. Habe den von Scott Klement im Einsatz

NEich
02-03-06, 10:32
Danke für die schnelle Antwort, habs mal geprüft:
Der Port auf dem Server ist korrekt (Port 80 - unser standard webserver) und ist auch normal ansprechbar (Browser), eine Firewall ist nicht dazwischen, Client sowohl Server befinden sich im gleichen Subnetz. Port-Einschränkungen sind auf der iSeries nicht vorhanden. Die Ports werden aufgemacht, eine Verbindung wird korrekt hergestellt.

Am Server scheints übrigens nicht zu liegen, ich habs mit dem Apache auf unserer iSeries, sowie mit einem Tomcat auf einem PC-Server probiert, beides mal das gleiche Problem des "hängenbleibens".

BenderD
02-03-06, 10:41
Hallo,

am Server kanns nicht liegen, wenn dein Java Programm gefunzt hat...
ich würde mir das Gedöns mit den Sockets nicht antun, sondern das zugrunde liegende Java Problem heilen!
Das Problem ist der synchrone JNI Call, da der erst mal eine JVM startet und das dauert und frisst zudem endlos Ressourcen, wenn das in jedem Job passiert (deshalb geht das auch relativ einfach aus RPG - Nachtigall ick hör die trapsen), lediglich die as400 hat dann die Vogelgrippe.
Am einfachsten machst du aus deinem Java Programm einen kleinen Serverdienst, der einmal gestartet wird und dann an einer DTAQ wartet, für jeden Job eine AntwortQ erstellt und dort seine Antworten sendet. Ansonsten alles wie gehabt. Für das RPG Programm machst du dann ein kleines Serviceprogramm, das die Aufrufe aus deinen Anwendungen vereinfacht.

mfg

Dieter Bender



Danke für die schnelle Antwort, habs mal geprüft:
Der Port auf dem Server ist korrekt (Port 80 - unser standard webserver) und ist auch normal ansprechbar (Browser), eine Firewall ist nicht dazwischen, Client sowohl Server befinden sich im gleichen Subnetz. Port-Einschränkungen sind auf der iSeries nicht vorhanden. Die Ports werden aufgemacht, eine Verbindung wird korrekt hergestellt.

Am Server scheints übrigens nicht zu liegen, ich habs mit dem Apache auf unserer iSeries, sowie mit einem Tomcat auf einem PC-Server probiert, beides mal das gleiche Problem des "hängenbleibens".

NEich
06-03-06, 14:49
Danke für die Antworten,
mit einem Dauerjob läufts nun erträglicherweise (Entweder ich bin nicht für den produktiven Einsatz geeignet oder Java)

Warum aber die Sockets auf unserem System Schwierigkeiten machen (bei anderen scheints ja zu funktionieren) ist mir immer noch schleierhaft.