[edit] here's a simpler version of the same problem. This code:
for(int i = 0; i <= 255; i++)
{
out.write(i);
}
(assuming that out is an open socket)
sends the same data (below); basically, 0x80 - 0x9F get sent as 0x3F ('?')
[/edit]
I'm trying to write a simple Socket wrapper. So far, I have this:
/*
* Socket.java
*
* Created on January 2, 2004, 5:27 AM
*/
/**
*
* @author Ron
*/
import java.io.*;
import java.net.*;
public class SimpleSocket
{
protected Socket botSocket = null;
protected PrintWriterFlush out = null;
protected BufferedReader in = null;
protected DataInputStream inData = null;
/** Creates a new instance of SimpleSocket */
public SimpleSocket()
{
}
public boolean connect(String server, int port)
{
// Create the socket
try
{
botSocket = new Socket(server, port);
// Bind it to a reader and a writer
out = new PrintWriterFlush(botSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(botSocket.getInputStream()));
inData = new DataInputStream(botSocket.getInputStream());
return true;
}
catch(IOException e)
{
System.err.println(e.toString());
return false;
}
}
public boolean disconnect()
{
try
{
if(in != null)
in.close();
if(out != null)
out.close();
if(botSocket.isClosed() == false)
botSocket.close();
}
catch(IOException e)
{
Interface.error(e.toString());
return false;
}
return true;
}
// Returns true if the socket is connected, false otherwise
public boolean isConnected()
{
return ( (botSocket != null) && (out != null) && (!botSocket.isClosed()) );
}
// Send outgoing chat data
// By default, just print it to the socket
public boolean sendString(String str)
{
if(isConnected())
{
out.print(str);
return true;
}
else
{
return false;
}
}
// Send a buffer
public boolean sendBuffer(Buffer buf)
{
if(isConnected() == false)
{
return false;
}
while(buf.length() != 0)
{
out.write(((int)buf.removeByte()) & 0x000000FF);
}
out.flush();
return true;
}
// Test this stuff out
public static void main(String args[]) throws IOException
{
SimpleSocket sck = new SimpleSocket();
sck.connect("127.0.0.1", 1234);
Buffer test = new Buffer();
for(int i = 0; i < 256; i++)
{
test.addByte((byte)i);
}
sck.sendBuffer(test);
}
}
At the other end, I recieve this:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
Which is, in ascii,
................
................
!"#$%&'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_
`abcdefghijklmno
pqrstuvwxyz{|}~
????????????????
????????????????
¡¢£¤¥¦§¨©ª«¬®¯
°±²³´µ¶·¸¹º»¼½¾¿
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
ÐÑÒÓÔÕÖרÙÚÛÜÝÞß
àáâãäåæçèéêëìíîï
ðñòóôõö÷øùúûüýþÿ
Any idea why 0x80 - 0x9F would get screwed up between the write() and when the data is sent?
My guess is that Java is trying to treat your data as Unicode, then converting those characters to ? when it can't find a match trying to smash them back into a normal char. I'd suggest playing around with different text encodings, but not sure if that'll work; I've only had to deal with Java screwing up upper-ascii characters on one occasion, and I ended up just putting a "Don't do that" note by it. :P
haha, well that's not really an option here. And I don't know how it's using unicode characters, though, since I'm converting the byte to an int, and using write on the int. Hmmm.. I can't think of any way around it. I may have to email my prof on this one, he knows everything :)
In case somebody wants to know, I found a class that works: OutputStreamWriter (http://java.sun.com/j2se/1.4.1/docs/api/java/io/OutputStreamWriter.html)
Here's how I use it. First, bind it to the socket's output stream, and set it to the right CharSet:
OutputStreamWriter out = new OutputStreamWriter(mySocket.getOutputStream(), "ISO-8859-1");
Then to write to it, just call a series of writes, then flush:
for(int i = 0; i < 256; i++)
{
out.write(i);
}
out.flush();
And then life is good! I'm going to finish up SimpleSocket then post it here this morning, probably.
What's the point of this?
Of what? I was having a problem, I asked for help, I solved it, and I posted my solution so that others could learn off it. That was the point.
Of the socket wrapper. Seems to be wrapped enough already.
I wouldn't say that. I want to get it the way I like it, so I'm doing it myself. The fact that I'm having these problems is proof enough the current socket stuff isn't good enough for me :P
*puzzle* ::)