Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Reading from a Socket's InputStream
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Reading from a Socket's InputStream



I have a client/server application suite built using J2SE. The two applications communicate using HTTP. The client connects to the server using the high-level URL and HttpURLConnection classes. The server listen for and services client requests using the low-level ServerSocketChannel and SocketChannel classes. The problem I'd like some advice on occurs when the server tries to read the content of a client's PUT (or POST) request. The server discovers the content length by querying the Content-Length HTTP header. But only a portion of the data can be read from the server's InputStream. After a certain point the server ends up permanently blocked as it tries to read the number of bytes indicated by the value of the Content-Length header.


Now here's the kicker... It only happens (and always happens) if either the client or server or both are MacOSX.



I have several years experience working with Java. But I also know there are programmers out there with a much firmer grasp on the environment than I do. So I'd appreciate any help that might come my way. What I'd like to do is articulate all the obvious questions someone might have about my problem and hope that the participants of this forum can help me zero in on what I'm doing wrong -- or what is wrong with the Mac JVM, if that ends up being the case (it never does).


* The problem occurs when 1) the client is running under MacOSX and the server is running under Windows XP, 2) client = XP & server = Mac, or 3) client = Mac & server = Mac. The problem does not occur if both client and server are XP based -- whether on the same XP box or different ones.

* All participants are on the same subnet (or even on the same machine). The activity monitors on all machines show reasonable CPU and network traffic.

*If I suspend the blocked client thread the stack crawl looks like the following...

Thread [Thread-5] (Suspended)
SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int) line: not available [native method]
SocketInputStream.read(byte[], int, int) line: 129
BufferedInputStream.fill() line: 183
BufferedInputStream.read1(byte[], int, int) line: 222
BufferedInputStream.read(byte[], int, int) line: 277
HttpClient.parseHTTPHeader(MessageHeader, ProgressEntry) line: 760
HttpClient.parseHTTP(MessageHeader, ProgressEntry) line: 711
HttpURLConnection.getInputStream() line: 635
HttpURLConnection(HttpURLConnection).getResponseCode() line: 272
HTTPConnect.getResponseCode() line: 104
HTTPServiceConnection.getResponseCode(boolean) line: 213
HTTPServiceConnection.performOp(int) line: 274
RegisterLocation.doWork(ServiceConnection) line: 53
RegisterLocation(PutMasterImages).doTask() line: 68
Interaction.doTask() line: 106
Interaction(FsmJob).doIt() line: 59
Interaction(ThreadJob).doItImpl() line: 36
ThreadJob.access$0(ThreadJob) line: 35
ThreadJob$JobThread.run() line: 98


* The client code that is writing the outgoing content looks something like this...

public static byte[] writeBytes(HttpURLConnection aConnection, byte [] aBytes) throws IOException {
OutputStream os = aConnection.getOutputStream();

try {
os.write(aBytes);
}
catch (IOException ioe) {
ioe.printStackTrace();
throw ioe;
}
finally {
os.close();
}
}



*A stack crawl of the reading server thread looks like this...

Thread [Thread-7] (Suspended)
SocketDispatcher.read0(FileDescriptor, long, int) line: not available [native method]
SocketDispatcher.read(FileDescriptor, long, int) line: 25
IOUtil.readIntoNativeBuffer(FileDescriptor, ByteBuffer, long, NativeDispatcher, Object) line: 233
IOUtil.read(FileDescriptor, ByteBuffer, long, NativeDispatcher, Object) line: 206
SocketChannelImpl.read(ByteBuffer) line: 207
SocketAdaptor$SocketInputStream.read(ByteBuffer) line: 171
SocketAdaptor$SocketInputStream(ChannelInputStream).read(byte[], int, int) line: 86
Parser.readBytes(InputStream, int) line: 590
ServerLocation.receive(Location, ServerConnection, Transaction) line: 171
RegistryServer.onPut(ServerConnection, Transaction) line: 72
RegistryServer(BaseServer).handleOp(int, ServerConnection, Transaction) line: 86
HTTPServerEndpoint.onGetPut(int) line: 769
HTTPServerEndpoint.handle() line: 295
HTTPServerRegister$TransactionThread.doInit() line: 423
HTTPServerRegister$TransactionThread(FsmJob).doIt() line: 54
HTTPServerRegister$TransactionThread(ThreadJob).doItImpl() line: 36
ThreadJob.access$100(ThreadJob) line: 11
ThreadJob$JobThread.run() line: 98


* The server code that is attempting to read the incoming content looks something like this...

public static byte[] readBytes(SocketChannel aSocketChannel, int aMaxBytes) throws IOException {
InputStream stream = Channels.newInputStream(aSocketChannel);
// InputStream stream = aSocketChannel.socket().getInputStream (); // either way
int length = 0;
byte[] bytes = new byte[aMaxBytes];


		while (length < aMaxBytes) {
			int count = stream.read(bytes, length, aMaxBytes - length);

			if (count < 0) {
				byte[] buffer = new byte[length];

				System.arraycopy(bytes, 0, buffer, 0, length);

				return buffer;
			}

			length += count;
		}

		return bytes;
	}


* The content that is being exchanged from client to server is textual. But the encoding of bytes to characters (and back) is done using the same character set on both sides. The problem occurs regardless of which encoding I use (UTF-8 or ISO8859-1).


* I can see from dumping the data to a console window that the content being received is the end part of what is being sent. Stated the other way, the part of the text that I'm sending that is not being received is the beginning. So if the text being sent consists of 100 lines, for example, I'm receiving something like the final 60 lines of that text on the receiving end.

Any suggestions would be greatly appreciated.

- Sparky

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden




Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.