views:

487

answers:

3

Erm, I'm new to sockets and even newer to Java, so the Java side is basically copied and pasted. The C# side is a little more self-made.

I've come to think that it may be some difference in the way Java and C# interpret strings; I've gotten it to partially work using the now deprecated "readLine" method in Java.

On the C# side:

    private void pollChat()
    {
        while (clientSocket.Connected)
        {
            try
            {
                NetworkStream serverStream = clientSocket.GetStream();

                byte[] inStream = new byte[10025];
                serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
                string returndata = System.Text.Encoding.UTF8.GetString(inStream);
                msg(returndata);
            }
            catch (SocketException)
            {
                clientSocket.Close();
                msg("Socket Exception");
            }
        }
    }

... for receiving things, (I changed System.Text.Encoding.ASCII to UTF8, but it didn't help) ... and

                NetworkStream serverStream = clientSocket.GetStream();
                byte[] outStream = System.Text.Encoding.UTF8.GetBytes(nickname + ": " + textBoxToSubmit.Text + "$");
                serverStream.Write(outStream, 0, outStream.Length);
                serverStream.Flush();

... for sending things.

On the Java server side...

void sendToAll( String message ) {

    synchronized( outputStreams ) {

        for (Enumeration e = getOutputStreams(); e.hasMoreElements(); ) {

            DataOutputStream dout = (DataOutputStream)e.nextElement();

            try {
                dout.writeBytes( message );
            } catch( IOException ie ) { System.out.println( ie ); }

        }
    }
}

... for sending things, and

        while (true) {

            // ... read the next message ...
            String message = din.readUTF();

            // ... tell the world ...
            System.out.println( "Sending "+message );

            // ... and have the server send it to all clients
            server.sendToAll( message );

        }

... for receiving things.

I apologize for the giant amount of pasted code, but please bear with me.

Thanks in advance!

A: 

The first thing I notice is that you're trying to read a Unicode string directly from a stream. This is problematic for two reasons.

  1. UTF characters are two bytes so calling a read when you have an odd number of bytes in your buffer is either going to block or just cause garbage to come out. Neither one is preferable.
  2. When you convert your string to bytes in C# and send them off there's no header specifying the length of the data nor is there a terminator character specified so there's no way to tell at the receiving end (Java in this case) if the string is complete.

I wouldn't recommend using readUTF or any function besides the one that pulls out raw bytes. Once you've handled the two issues I've noted above you'll have a byte array with a complete message. Only then should you try to convert the bytes into their proper encoding scheme.

Spencer Ruport
Please see the "answer" that I posted.Thanks!
Jonathan Chan
A: 

This is supposed to be a reply to Spencer Ruport's answer, but you can't put formatted code in comments...

So, would this work? I'm sure that it isn't a very elegant solution, but it seems to get the job done.

            char c;
            int currentchar = 0;
            String strMessage = "";

            while ((c = (char) din.read()) != -1 && c != '$') {
                strMessage = strMessage + (char) c;
                currentchar ++;
                System.out.print(c);
            }
            System.out.println("And the results show that...");
            System.out.println(strMessage);

Thanks!

Jonathan Chan
A: 

You need to do message framing.

Also the following article might be helpful: http://ferozedaud.blogspot.com/2009/11/how-to-send-object-from-java-to-net.html

feroze
I see. Thanks for the helpful link!
Jonathan Chan