Egne nettverksprogrammer?

De ferdige nettverksklientene du har på maskinen din (E-post, Web-leser m.m.) er utmerket for sitt formål. Men om du ønsker en annen slags behandling av informasjonen der ute, ja da kan det hende at du må lage programmet selv.
Trykket i PC World Nettverk nr.6/1998
(c) Anders Fongen 1998

Anders Fongen er Høgskolelektor ved Den Polytekniske Høgskolen i Bærum, Web-stedet hans er på www.fongen.no

Og vi kan berolige dere med at det er ikke så vanskelig for en person med noe programmeringserfaring i et språk som f.eks. Java, C++ eller Perl. Flere av språkene kommer med samlinger av hjelperutiner for å bringe deg et stykke på vei.

Det er mange slags anvendelser hvor du kan ha nytte av å få et mer direkte grep om den informasjonen som du henter inn via Internet. Her noen eksempler:
 

  1. Du ønsker å være orientert om temperaturen i Vancouver, Canada. Du vet også om et web-sted som hele tiden viser denne temperaturen. Da kan du lage et program som hver time henter denne web-siden, finner frem til selve tallet ved å søke gjennom HTML-teksten, og som deretter sender dette tallet som en SMS-melding til din mobiltelefon (det gjør den som en E-post melding). Enkelte nettsteder tilbyr allerede slike tjenester for de mest populære opplysningene, men sikkert ikke for akkurat den informasjonen som du er insteressert i.
  2. Du ønsker å samle all informasjon fra en Internet-konferanse (news) som vedrører et bestemt tema. Du kan lage et program som setter opp en forbindelse til en konferansetjener, henter ut alle overskrifter på nye innlegg i denne konferansen, og som deretter søker etter ord eller ordkombinasjoner i overskriftene. De innleggene som passer kan automatisk hentes ned over nettet og lagres på den måten du velger, f.eks. i et søkbart tekstarkiv.
  3. Du har et web-sted, og kundene dine ønsker å oppdatere sine web-sider gjennom å sende E-post til en spesiell E-postboks. Denne meldingen bør inneholde en slags autentisering i form av et passord, gjerne et passord som endrer seg hver gang. Utover dette kan meldingen inneholde HTML-kodet tekst som legges inn på et angitt sted i web-tjeneren, eller et utfylt skjema som oppdaterer en database som web-tjeneren benytter seg av. En slik tjeneste kan dessuten kombineres med noen slags konverteringstjeneste, hvor avsenderen f.eks. kan vedlegge et Word-dokument i meldingen som blir konvertert til PDF-format før den legges ut på web-tjenerens filområde.
Men ingen av disse anvendelsene er noe kan kjøpe ferdig i et programvareprodukt. Det er noe som du må programmere selv, og da trenger du noe kunnskap om programmering og programmeringsspråk. Dessuten trenger du kunnskap om hvordan du kan sette opp og trafikere en nettverksforbindelse med det programmeringsspråket du velger, og du trenger opplysninger om de nettverksprotokollene som benyttes av World Wide Web, Internet-konferanser og E-post. Noe av dette vil vi forsøke å hjelpe deg med i denne artikkelen.

Nettverksprotokoller

Internet er fornuftens gjennombrudd. Mens store deler av datakommunikasjonsmiljøet satt på internasjonale konferanser og laget overkompliserte og uforståelige kommunikasjonsprotokoller som skulle dekke opp for de mest søkte eventualiteter (her sikter jeg til utviklingen av OSI-protokollene), drev miljøet rundt Arpanet/NSF/Internet utvikling på en helt annen måte: Her kunne alle som hadde noe på hjertet sende inn såkalte RFC-dokumenter (Request For Comment) med forslag til tilpasninger eller videreutvikling, og den teknologien som ble utviklet var ikke mer komplisert enn det som var nødvendig for å løse det foreliggende problemet. Ikke-problemer fikk være i fred.

Alle Internet-standardene, inkludert de som beskriver hvordan du henter E-post, konferanseinnlegg og web-sider, er beskrevet i noen av disse RFC-dokumentene. De er enkle å få tak i, de er lesbare og mulige å teste ut på egen hånd med et enkelt nettverksprogram som “telnet”.

Telnet, til vanlig programmet for terminalemulering i Internet, gir det et godt innblikk i hvor enkle disse protokollene er. Skriv kommandoen “telnet www.fongen.no 80” i et kommandovindu. Når forbindelsen er opprettet, skriv i telnet-vinduet “GET /publik.htm HTTP1.0” etterfulgt av to linjeskift. Da ruller innholdet av “www.fongen.no/publik.htm” over skjermen, med noen innledende opplysninger først. Du kan på tilsvarende måte teste ut forskjellige feilsituasjoner og finesser i HTTP-protokollen. Når du deretter tar fatt på lesningen av RFC 1945, som beskriver HTTP-protokollen nøyaktig, blir det litt lettere å forstå detaljene i teksten.

Dessuten er det god tilgang på public-domain kode som viser eksempler på kode som betjener disse nettverksprotokollene på flere forskjellige programmeringsspråk.

Kjennskap til disse “applikasjonsprotokollene” kan dessuten by på en og annen spøk: Før i tiden var det å manipulere avsenderadressen på den E-posten man sendte ikke så enkelt. Derimot, ved å starte “telnet” mot port 25 på en E-post tjener, var det mulig å forfalske denne adressen ved selv å “snakke” SMTP-protokoll (RFC 821). I et annet tilfelle var det noen som fikk nettleseren “lynx” til å vises som den mest populære leseren på et nettsted gjennom å bombardere nettstedet (vi mener å huske at dette var Dagbladet) med HTTP-meldinger som oppga å være fra “lynx”.

Hvilket programmeringsspråk?

Nå bør du være igang med å “leke deg med” en eller annen nettverksprotokoll, teste ut forskjellige feilsituasjoner, og sammenligne resultatet med det som står i RFC-dokumentet. Når du så ønsker å lage et program som f.eks. henter ut konferanseinnlegg automatisk, hvilket programmeringsspråk skal du da benytte deg av?

Det er gjerne slik at svaret gir seg selv, ut fra hvilken kompilator du har tilgjengelig, eller hva du ellers benytter deg av. Det er allikevel nyttig å vite at de ulike språkene tilbyr litt forskjellig hjelp til de operasjonene som du trenger å ha “i bunnen” av programmet ditt:
 

Selv har vi laget nettverksprotokoller med C++, Java og Perl, så våre kommentarer på programmeringsspråk begrenser seg til disse tre:

Java er det språket som har den beste støtten for nettverksprotokoller i form av klassebiblioteker. Spesielt er HTTP-protokollen godt støttet. Dokumentasjonen av støtteklassene er dårlig, så det kan være vanskelig å komme igang med å bruke dem. I Java kan du lage en tidsutløser gjennom “Thread”-klassen: En egen Thread holder rede på hvor lenge du har ventet, og tar kontrollen når tiden er ute.

Perl har i utgangspunktet kun støtte for såkalte Berkeley-sockets, som er et grensesnitt til TCP-protokollene. Du kan sette opp forbindelser til en nettverkstjener (ganske mystisk kode, men det finnes gode eksempler du kan se på), og lese og skrive med vanlige I/O-operasjoner. Du må bygge en tidsutløser på UNIX-lignende mekanismer som alarmer og signal-feller (signal traps). Perl har derimot god støtte for nettverksprotokoller gjennom et omfattende kodebibliotek som heter “libwww”. Dessuten er Perl-koden ganske portabel, det er praktisk talt ingen forskjeller på koden som kjører under UNIX eller et Windows-OS.

C++ er ganske avhengig av hva slags kompilator du bruker. På UNIX (i vårt tilfelle LINUX) har du alltid tilgang på Berkeley-sockets, men fra en Windows-basert kompilator som Borland C++ har du et eget klassebibliotek for “Winsock”, som er Windows-varianten av Berkeley-sockets. Ikke veldig ulik, men nok til at C++ programmet blir ulikt for Windows- og UNIX-versjon. Ikke særlig hyggelig. Dessuten får du ingen ekstra hjelp til å lage en tidsutløser: På UNIX kan du lage en “alarm”-mekanisme tilsvarende som i Perl. Til C++ sitt forsvar antar vi at det er gode ekstrabiblioteker som kan kjøpes. Det kan godt vise seg å være verd bryderiet dersom du har en jobb som må gjøres fort.



For å få tak i f.eks. RFC 1945 henter du filen:
ftp://sunsite.uio.no/pub/rfc1945.txt


Nyttige RFC’er:
RFC  821 Simple Mail Transfer Protocol (SMTP)
RFC  822 Beskriver kodingen av E-post meldinger
RFC  977 Network News Transfer Protocol (NNTP)
RFC 1521 Multipurpose Internet Mail Extension (MIME) part 1
RFC 1522 Multipurpose Internet Mail Extension (MIME) part 2
RFC 1725 Post Office Protocol - v.3
RFC 1945 Hypertext Ttransfer Protocol (HTTP) 1.0

C++ klasse for å sette opp en TCP-forbindelse

// C++ class for making a client tcp socket, and for writing
// and reading data on that socket. Uses Berkeley sockets
// Anders Fongen, 18.9.98

#include <iostream.h>
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>

class ClientSocket {
private:
  FILE *fileIn, *fileOut;
  int sock;
  char status[40];
public:
  ClientSocket(char*, char*);
  void readString(char*, int);
  void writeString(char*);
  char* showStatus();
};
 

ClientSocket::ClientSocket(char *host, char *service) {
  struct sockaddr_in addr;
  struct hostent *hp;
  struct servent *sp;

  if ((hp = gethostbyname(host)) == NULL) {
    strcpy(status,"Host name error");
    return;
  }

  if ((sp = getservbyname(service,"tcp")) == NULL) {
    strcpy(status,"Service name error");
    return;
  }

  bzero((char*)&addr,sizeof(addr));
  addr.sin_family = AF_INET;
  bcopy(hp->h_addr,(char*)&addr.sin_addr, hp->h_length);
  addr.sin_port = sp->s_port;

  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    strcpy(status,"Socket error");
    return;
  }

  if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
    strcpy(status,"Connect error");
    close(sock);
    return;
  }

  fileIn  = fdopen(sock, "r");
  fileOut = fdopen(sock, "w");
  status[0] = '\0';
  cout << "Socket operation OK\n";
}

void ClientSocket::readString(char *buffer, int maxlen) {
  fgets(buffer,maxlen,fileIn);
}

void ClientSocket::writeString(char *buffer) {
  fprintf(fileOut,"%s\n",buffer);
}

char* ClientSocket::showStatus() { return status; }