[jcifs] Problem reading multiple writes from named pipe
Michael B.Allen
Michael_B_Allen at ml.com
Wed Apr 9 12:31:54 EST 2003
On Mon, 7 Apr 2003 17:01:38 -0400
"Eric Sword" <ericsword at grouplogic.com> wrote:
> I am having a problem reading data from a pipe when it was written using
> more than one WriteFile call in a C++ app. The setup is pretty standard
> - I'm am using slightly modified copies of the sample apps createnp and
> CallNamedPipe. The Java app reads from stdin, sends to the C++ app, and
> the C++ app echos it back in 2 sends. The first send contains only an
> int which is the length of the second send (matching an existing
> protocol I am working with).
>
> I have tried multiple ways of setting up the pipe (just PIPE_TYPE_RDWR,
> PIPE_TYPE_RDWR | PIPE_TYPE_CALL, and PIPE_TYPE_RDWR |
> PIPE_TYPE_TRANSACT), properly changing the pipe URL for each. Each way,
> I can send data over the pipe just fine and I get back the int from the
> first send, but block indefinitely waiting for the info from the second
> message.
I don't think it makes sense to use PIPE_TYPE_CALL or PIPE_TYPE_TRANSACT
because those send a message and get a response on *one round trip*
whereas without PIPE_TYPE_CALL or PIPE_TYPE_TRANSACT you try to read
which blocks and then write and get a write response and finally the
read returns with the result. If you do not use PIPE_TYPE_CALL or
PIPE_TYPE_TRANSACT what you describe works. I modified createnp.c to
write a 0xFF byte for each message read like:
154 while(ReadFile(inFile, buf, bufferSize, &bytesRead, NULL) > 0) {
155 char b = 0xFF;
156 int tmp;
157 WriteFile(outFile, &b, 1, &tmp, NULL);
158 WriteFile(outFile, buf, bytesRead, &bytesRead, NULL);
159 }
ran it with:
C:\Temp> createnp \\.\pipe\foo
and took a capture of the following PipeTalk:
$ java -Djcifs.properties=jcifs.prp PipeTalk "smb://miallen2/IPC$/foo"
hello
hello
ÿ
hello
yoyoyo
yoyoyo
ÿ
yoyoyo
and I can see that two separate packets are sent in the response for
the WriteFile calls. So it works.
> [code snippet]
>
> //first read the length of the message - stored in the first 4 bytes
> length = sd_istream.readInt();
> System.out.println("Message Length: " + length);
>
> //now read the message
> int numRead = in.read(temp);
> String tempString = new String(temp, 0, numRead);
>
> [end snippet]
>
> If I just do the single in.read, it will also only find 4 bytes to read
> in.
>
> Suggestions?
If you want to use PIPE_TYPE_CALL or PIPE_TYPE_TRANSACT you cannot
write each field separately. This is generally true of any network
programming. Instead you must encode the message format into a buffer
and write the entire buffer in one write call. Actually I have a library
written in C that could help you with this. I describe how one might
use it in this message:
http://groups.google.com/groups?selm=20021117.034856.502278611.10307%40eskimo.com
I think this might apply to you.
Mike
More information about the jcifs
mailing list