File: win.pl

package info (click to toggle)
swi-prolog 9.0.4%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 82,408 kB
  • sloc: ansic: 387,503; perl: 359,326; cpp: 6,613; lisp: 6,247; java: 5,540; sh: 3,147; javascript: 2,668; python: 1,900; ruby: 1,594; yacc: 845; makefile: 428; xml: 317; sed: 12; sql: 6
file content (116 lines) | stat: -rw-r--r-- 2,810 bytes parent folder | download | duplicates (4)
1
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
110
111
112
113
114
115
116
/*  Part of SWI-Prolog

    Author:  Jan Wielemaker
    This example code is in the public domain
*/

:- asserta(library_directory('.')).
:- asserta(user:file_search_path(foreign, '.')).
:- use_module(library(socket)).

                 /*******************************
                 *        SOCKET (CLIENT)       *
                 *******************************/

get_http_data(Host, URL) :-
    tcp_socket(Socket),
    tcp_connect(Socket, Host:80),
    tcp_open_socket(Socket, Read, Write),
    format(Write, 'GET ~w~n~n', URL),
    flush_output(Write),
    copy_stream(Read, user_output),
    close(Read),
    close(Write).

copy_stream(In, Out) :-
    get0(In, C0),
    copy_stream(C0, In, Out).

copy_stream(-1, _, _) :- !.
copy_stream(C, In, Out) :-
    put(Out, C),
    get0(In, C2),
    copy_stream(C2, In, Out).


                 /*******************************
                 *         SOCKET (SERVER)      *
                 *******************************/

:- dynamic
        server/1,
        client/2.

mkserver :-
    mkserver(3000).
mkserver(Port) :-
    tcp_socket(Socket),
    tcp_bind(Socket, Port),
    tcp_listen(Socket, 5),
    tcp_open_socket(Socket, Read, _),
    asserta(server(Read)).

dispatch :-
    repeat,
    \+ dispatch1, !.

dispatch1 :-
    findall(C, client(C, _), Clients),
    server(Server),
    wait_for_input([Server|Clients], Ready, 0),
    dispatch(Ready).

dispatch([]).
dispatch([H|T]) :-
    format('Dispatching ~w ... ', [H]), flush,
    dispatch_fd(H),
    format('ok~n'),
    dispatch(T).

dispatch_fd(Server) :-
    server(Server), !,
    tcp_accept(Server, ClientSocket, Peer),
    format('Connected from ~w~n', [Peer]),
    tcp_fcntl(ClientSocket, setfl, nonblock),
    tcp_open_socket(ClientSocket, Read, Write),
    format(Write, 'Please to meet you!~n', []),
    flush_output(Write),
    assert(client(Read, Write)).
dispatch_fd(Client) :-
    client(Client, Write),
    format(Write, 'You typed: ', []),
    copy_stream(Client, Write),
    (   at_end_of_stream(Client)
    ->  format('Closing client ~w~n', [Client]),
        close(Client),
        close(Write),
        retractall(client(Client, _))
    ;   flush_output(Write)
    ).

                 /*******************************
                 *              CLIENT          *
                 *******************************/

client :-
    client(3000).
client(Port) :-
    tcp_socket(Socket),
    tcp_connect(Socket, localhost:Port),
    tcp_open_socket(Socket, In, Out),
    format(Out, 'Hello World~n', []),
    flush_output(Out),
    copy_line(In, user_output),
    close(In),
    close(Out).

copy_line(In, Out) :-
    get0(In, C0),
    copy_line(C0, In, Out).

copy_line(10, _, _) :- !.
copy_line(C, In, Out) :-
    put(Out, C),
    get0(In, C2),
    copy_line(C2, In, Out).