Different socket behaviour between windows and linux VMs?

Simon Holgate sqk at simonholgate.org.uk
Wed Jan 29 17:19:45 UTC 2003


I've found an inconsistency between the linux and windows VMs which is 
puzzling me. I have a java server running which simply returns a small 
integer (2 bytes) and prints some junk to the screen - the junk turns 
out to be significant.

This works fine on linux and returns both bytes to my squeak client. On 
windows I only get the 1st byte, unless very little else happens after 
the integer is sent.

I've attached some examples to try and show what I mean.  Start one of 
the servers with e.g. java TCPServer1E2 (it listens on port 7000), then 
in a workspace (with a Transcript open) do: Socket remoteTestJavaTCP. 
The first "server" (TCPServer1E2) waits for a connection, sends a 2 byte 
integer (258), flushes the buffer then writes out 1 to 100 to the 
screen. No problem here, both the linux and windows squeak clients 
receive 258. The second byte is written to the Transcript which is 2 in 
each case.

The second server does the same, except that after the buffer flush it 
writes 1 to 100 000 out to the screen. In this case linux client gets 2 
bytes but windows client only gets 1 byte! (Transcript shows 0 and 
inspecting the stream shows only 1 byte received).

Confusingly, if the writing to screen is taken out and replaced simply 
by a counting loop both linux and windows clients work fine. The 
out.flush() method seems not to make any difference. out.close() does 
work but rather defeats the object since I want to keep the socket alive 
to send back other data.

There is a practical aspect to this because I've been playing with Avi 
Bryant's JDBCBridge to connect to Oracle, which I want to work on both 
linux and windows. Connection to the database is confirmed by writing a 
short integer back to the client but this fails under windows because 
(although not writing to screen) the server then waits for SQL queries 
to be sent. This waiting causes the socket to be reset by the windows 
client (which has only received 1 byte).

I don't know whether the problem is with the windows VM or the windows 
socket layer. Any insights would be much appreciated.

    Cheers,

        Simon
-------------- next part --------------
import java.io.*;
import java.util.*;
import java.net.*;

public class TCPServer1E5 implements Runnable
{
	Socket socket;
	DataOutputStream out;
	BufferedReader in;
	
	private void connect()
		throws IOException
	{
			out.writeShort(258);
			out.flush();
			for (int i=0; i < 1e5; i++){
				System.out.print(i+" ");
			}
			System.out.println("");
    // Close the connection
    System.out.println("DISCONNECTED");
    System.out.flush();
	}
		
	public void run()	
	{
		try
		{
			connect();
		}
		catch(Exception e)
		{
			System.out.println("Error: " + e + "\n  Closing connection to " + socket.getInetAddress());
			e.printStackTrace();
		}
		finally
		{
			System.out.println("Closing connection to " + socket.getInetAddress());
			try { socket.close(); } catch(Exception e) {}
		}
	}
	
	public TCPServer1E5(Socket socket)
	{
		try
		{
			this.socket = socket;
			out = new DataOutputStream(
				socket.getOutputStream());
			in = new BufferedReader(
				new InputStreamReader(
				socket.getInputStream()));
		}
		catch(IOException e)
		{
			System.out.println("Could not initialize socket");
			System.exit(0);
		}
	}
	
	public static void main(String[] args)
		throws IOException
	{
		int port = 7000;
		if(args.length >= 1)
			port = Integer.parseInt(args[0]);

		ServerSocket server = new ServerSocket(port);
		System.out.println("Listening on port " + port);
		
		while(true)
		{
			Socket s = server.accept();
			System.out.println("Connected to " + s.getInetAddress());
				
			TCPServer1E5 j = new TCPServer1E5(s);
			Thread t = new Thread(j);
			t.start();
		}
	}
	
}	
-------------- next part --------------
A non-text attachment was scrubbed...
Name: TCPServer1E5.class
Type: application/octet-stream
Size: 2604 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20030129/23847ac1/TCPServer1E5.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: TCPServer1E2.class
Type: application/octet-stream
Size: 2604 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20030129/23847ac1/TCPServer1E2.obj
-------------- next part --------------
import java.io.*;
import java.util.*;
import java.net.*;

public class TCPServer1E2 implements Runnable
{
	Socket socket;
	DataOutputStream out;
	BufferedReader in;
	
	private void connect()
		throws IOException
	{
			out.writeShort(258);
			out.flush();
			for (int i=0; i < 1e2; i++){
				System.out.print(i+" ");
			}
			System.out.println("");
    // Close the connection
    System.out.println("DISCONNECTED");
    System.out.flush();
	}
		
	public void run()	
	{
		try
		{
			connect();
		}
		catch(Exception e)
		{
			System.out.println("Error: " + e + "\n  Closing connection to " + socket.getInetAddress());
			e.printStackTrace();
		}
		finally
		{
			System.out.println("Closing connection to " + socket.getInetAddress());
			try { socket.close(); } catch(Exception e) {}
		}
	}
	
	public TCPServer1E2(Socket socket)
	{
		try
		{
			this.socket = socket;
			out = new DataOutputStream(
				socket.getOutputStream());
			in = new BufferedReader(
				new InputStreamReader(
				socket.getInputStream()));
		}
		catch(IOException e)
		{
			System.out.println("Could not initialize socket");
			System.exit(0);
		}
	}
	
	public static void main(String[] args)
		throws IOException
	{
		int port = 7000;
		if(args.length >= 1)
			port = Integer.parseInt(args[0]);

		ServerSocket server = new ServerSocket(port);
		System.out.println("Listening on port " + port);
		
		while(true)
		{
			Socket s = server.accept();
			System.out.println("Connected to " + s.getInetAddress());
				
			TCPServer1E2 j = new TCPServer1E2(s);
			Thread t = new Thread(j);
			t.start();
		}
	}
	
}	
-------------- next part --------------
'From Squeak3.2.1 of '' 11 November 2002'' [latest update: #5106] on 29 January 2003 at 4:32:10 pm'!

!Socket class methodsFor: 'examples' stamp: 'sjh 1/29/2003 16:31'!
remoteTestJavaTCP
	"FIRST start up java server. Either:
	java TCPServer1E2 or java TCPServer1E5
	THEN come back to this image and execute:"
			"Socket remoteTestJavaTCP"

	| socket  receiveBuf  bytesReceived packetsReceived serverName portNumber |
	Transcript show: 'starting client/server TCP test'; cr.
	Transcript show: 'initializing network ... '.
	Socket initializeNetworkIfFail: [^Transcript show:'failed'].
	Transcript show:'ok';cr.
	socket _ Socket newTCP.
	serverName _ FillInTheBlank
		request: 'What is your remote Test Server?'
		initialAnswer: 'localhost'
		centerAt: Display center.
	portNumber _ FillInTheBlank
		request: 'What port number to connect to?'
		initialAnswer: '7000'
		centerAt: Display center.

	socket connectTo: (NetNameResolver addressForName: serverName) port: portNumber asNumber.
	socket waitForConnectionUntil: Socket standardDeadline.
	Transcript show: 'client endpoint created'; cr.

	receiveBuf _ String new: 80.	
	bytesReceived _  packetsReceived _ 0.

	socket waitForDataUntil: Socket standardDeadline.	
	socket dataAvailable
	ifTrue:
			[packetsReceived _ packetsReceived + 1.
			bytesReceived _ bytesReceived + (socket receiveDataInto: receiveBuf).]
	ifFalse:
			[Transcript show: 'No data available';cr.].

	Transcript show: ((receiveBuf at: 2) asciiValue) asString printString;cr.
    "receiveBuf inspect."

	socket closeAndDestroy.
	Transcript show: 'remoteClient TCP test done'; cr.
	Transcript show: packetsReceived printString, ' packets, ',
						bytesReceived printString, ' bytes received'; cr.! !


More information about the Squeak-dev mailing list