118 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			118 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
|   | /*  $Id$ | ||
|  | 
 | ||
|  |     Part of SWI-Prolog | ||
|  | 
 | ||
|  |     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). | ||
|  | 
 |