Arne Vajhøj wrote:
> KV wrote:
>> Jeg er ved at kode et helt simpelt program til Linux og har brug for, at
>> kunne henholdsvis GET og POST til en given URL og indlæse resultatet i en
>> variabel.
Finn ut hvordan sockets virker på din maskin. BSD-lignende utgaver finnes
for flere UNIX-varianter samt Windows.
>> Jeg vil helst ikke gøre brug af 3. parts source kode eller programmer
>> (f.eks. curl) men undgår jeg det? Det er vel ikke bare at åbne en fil
>> (ligesom fopen med PHP)?
BSD-sockets oppfører seg i stor grad som filer i UNIX.
> Du åbner en socket til port 80, skriver en GET eller POST request
> og læser response.
Hele HTTP-standarden finnes på w3.org
> GET format er:
>
> sprintf(cmd,"GET %s HTTP/1.1\r\nHost: %s\r\nConnection:
> close\r\n\r\n",path,hostname);
>
> POST format er:
>
> sprintf(cmd,"POST %s HTTP/1.1\r\nHost: %s\r\nConnection:
> close\r\nContent-Length: %d\r\n\r\n%s\r\n",
> path,hostname,strlen(args),args);
Her kommer et eksempel på en GET. Dette virker i Linux 2.6, men den har
ingen feilsjekking. I C er alle strukturene structs, og må opprettes
med «struct sockaddr». I tillegg skal/bør du bruke select før read og
write.
Alle disse detaljene tilsier vel at det er lurt å bruke et eller annet
bibliotek? Jeg har ikke testet koden på andre systemer.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
int main() {
//Lag socket (mye av det samme som filedescriptor fra open())
int sock = socket(PF_INET, SOCK_STREAM, 0);
// DNS-oppslag (finner IP-adressen fra URL)
hostent *add = gethostbyname("
www.riksmalsforbundet.no");
// IPv6: sockaddr_in6 sin
sockaddr_in sin;
memset(&sin, 0, sizeof sin);
// Internet IPv4.
// sin.sin6_family = AF_INET6 for IPv6.
// Bør matche add->h_addrtype
sin.sin_family = AF_INET;
// htons = host to network short. Tar hånd om endian-ting.
// 80 er standard http-port
sin.sin_port = htons(80);
// IPv4-adresse. GÃ¥r fryktelig galt hvis add->h_addrtype != AF_INET
// add->h_addr er en char* med bytene i adressen
// IPv6: sin.sin6_addr.s6_addr er en char[16]. se ipv6(7)
sin.sin_addr.s_addr = *reinterpret_cast<u_int32_t*>(add->h_addr);
// Opprette forbindelse
connect(sock, reinterpret_cast<sockaddr*>(&sin), sizeof sin);
// Skrive request.
char buf[] = "GET /ordliste/?T=sok&soketype=S&q=ord HTTP/1.1\r\n"
"Host:
www.riksmalsforbundet.no\r\n"
"Connection: close\r\n\r\n";
write(sock, buf, sizeof buf);
char ans[1024];
int s;
// Lese svar
while((s = read(sock, ans, sizeof ans)) > 0)
// Skrive til stdout.
write(1, ans, s);
}
--
Robert Bauck Hamar
Semikolon markerer en litt kortere pause enn punktum; det kan bare
stå mellom selvstendige setninger. Det er en moderne uskikk å bruke
semikolon istedenfor kolon. Følg ikke den uskikken!