First, to fix the hanging, you need to close the pipe on the server.
ods listing close;
I cannot explain having to run the client twice.
Changing the code to this works.
Server
FILENAME stdout namepipe '\\.\pipe\Sas\PipeOut' server eofconnect retry=15 block;
FILENAME DIRLIST pipe 'dir "C:\temp"';
data dirlist ;
length buffer $256;
infile dirlist length=reclen;
input buffer $varying256. reclen;
*file stdout;
*put buffer;
run;
ods listing file=stdout;
proc print data=dirlist;
run;
ods listing close;
Client
FILENAME stdin namepipe '\\.\pipe\Sas\PipeOut' client retry=15 ;
/*Extra read to clear whatever weirdness ODS does.*/
data _null_;
infile stdin;
input;
run;
data d1;
length buffer $ 256;
infile stdin length=reclen;
input buffer $varying256. reclen;
put buffer;
run;
I suspect, that the ODS statement does something to create a the file. This is a first write to the pipe. The next write to the pipe is a modification. That's why you have to read from it twice.
For your second question about sharing data. I am not sure you can pipe the dataset in binary form. You could write it as something like CSV to the pipe and read it into a data set on the client.
Server
FILENAME stdout namepipe '\\.\pipe\Sas\PipeOut' server eofconnect retry=15 block;
proc export data=sashelp.class outfile=stdout dbms=csv replace;
run;
filename stdout clear;
On the client you need to write the results to a temporary file. Proc IMPORT needs random access and a named pipe cannot be accessed randomly.
FILENAME stdin namepipe '\\.\pipe\Sas\PipeOut' client retry=15 ;
filename x temp;
data _null_;
length buffer $4000.;
infile stdin length=reclen;
file x;
input;
buffer = _infile_;
put buffer;
run;
proc import file=x out=class dbms=csv replace;
run;
filename x clear;