Client
Het is het makkelijkste voor mij om het client voorbeeld gewoon in PHP
te geven. In praktijk zal dit echter weinig zo voorkomen dat je er ook
PHP voor gebruikt. Om die reden ga ik nu eens aan de slag in C++.
C++ heeft ook een goede ondersteuning voor sockets, al is die wel net
een stapje krachtiger dan die van PHP. Als je echter ervaring hebt met
PHP sockets zal C++ je ook wel lukken. Let wel op dat ik het hier over
sockets heb en niet over fsockets!
Aangezien ik hier achter een Windows kast zit is de code daarvoor
gemaakt, converteren naar Linux is echter niet zo'n heel groot
probleem. Denk er wel aan dat je je Client linkt met het winsock2
library!
Tijd voor wat code, met natuurlijk het nodige commentaar.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <cstdlib>
#include <iostream>
// Sockets
#include <sys/types.h>
#include <winsock2.h>
// Defines
#define VERSION "1.0"
// STD namespace
using namespace std;
// Korte afsluit procedure
int quitMain()
{
system("pause");
return EXIT_SUCCESS;
}
// Hoofd functie
int main(int argc, char *argv[])
{
// Start winsock (2.2 indien beschikbaar, anders de hoogst mogelijke versie)
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
int err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
cout << "Fatal error: Couldn't startup WinSock" << endl;
return quitMain();
}
// Dit winsock stuk hoeft niet onder Linux
// Toon een versie regel en vraag informatie over de Server
string server;
string port;
string path;
cout << "LegolasWeb TimeRequestDemo " << VERSION << endl;
cout << endl;
cout << "Server: ";
cin >> server;
cout << "Port: ";
cin >> port;
cout << "Path: ";
cin >> path;
// Maak een socket
int sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
cout << "Fatal error: Couldn't create socket" << endl;
return quitMain();
}
// Maak verbinding met de Server (converteert eerst het Server adress
naar een IP-adress)
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(atoi(port.c_str()));
hostent* h = gethostbyname(server.c_str());
dest_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*)h->h_addr));
memset(&(dest_addr.sin_zero), '\0', 8);
int cerr = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct
sockaddr));
if (cerr != 0)
{
cout << "Fatal error: Couldn't connect" << endl;
return quitMain();
}
// Vertel eens wat
cout << "Connected" << endl;
cout << endl;
cout << "Requesting \"time?\"" << endl;
// Bouw een request
string request;
string ver = VERSION;
request += "POST " + path + " HTTP/1.0\r\n";
request += "Host: " + server + "\r\n";
request += "User-Agent: LegolasWeb TimeRequestDemo " + ver + "\r\n";
request += "Content-Length: 5\r\n";
request += "Connection: close\r\n";
request += "\r\n";
request += "time?\r\n";
// Verstuur het request en set nog eens een enter op het scherm
send(sock, request.c_str(), strlen(request.c_str()), 0);
cout << endl;
// Haal de response op
string out;
char output[1025];
while (recv(sock, output, 1024, 0) != 0)
{
out += output;
sprintf(output, "");
}
// Isoleer het body gedeelte en toon het
size_t location = out.find("\r\n\r\n") + 4;
cout << out.substr(location, 5) << endl;
cout << endl;
// Sluit af
return quitMain();
}
Om het dan toch compleet te maken voor de PHP'ers ook een klein PHP voorbeeldje.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Nodige informatie
define('SERVER', 'www.example.org');
define('PORT', 80);
define('PATH', '/example.php');
// Versie
define('VERSION', '1.0');
// End of line
define('_EOL', "\r\n");
// Maak een socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
if (!$sock) {
echo 'Fatal error: Couldn\'t create socket';
exit;
}
// Maak verbinding
if (!socket_connect($sock, SERVER, PORT)) {
echo 'Fatal error: Couldn\'t connect';
exit;
}
// Maak het request
$request = null;
$request .= 'POST ' . PATH . ' HTTP/1.0' . _EOL;
$request .= 'Host: ' . SERVER . _EOL;
$request .= 'User-Agent: LegolasWeb TimeRequestDemo ' . VERSION . _EOL;
$request .= 'Content-Length: 5' . _EOL;
$request .= 'Connection: close' . _EOL;
$request .= _EOL;
$request .= 'time?' . _EOL;
// En verstuur het
if (!socket_send($sock, $request, strlen($request), 0)) {
echo 'Fatal error: Couldn\'t send request';
exit;
}
// Haal de response op
$output = null;
$buffer = null;
while (socket_recv($sock, $buffer, 1024, 0) != 0) {
$output .= $buffer;
}
// Isoleer het body gedeelte en toon het
$output = explode(_EOL . _EOL, $output);
$output = substr($output[1], 0, 5);
echo $output;
?>