Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Telnet Commands are Always Corrupted by Linux?

124 views
Skip to first unread message

commie

unread,
Jan 4, 2005, 2:45:06 PM1/4/05
to
Hello everyone. I certainly hope someone can help me here.

I've written a mud (telnet server) in Java.

The client I am using for testing is a simple app that connects to the
mud server on the proper port and displays the decimal values of the
first 30 bytes sent out by the server.

When a connection is received by the server, the first data it sends
are some telnet negotiation data, which happens to be the following in
decimal:
255(IAC) 251(WILL) 91(MXP)

Whenever the server runs in a Windows environment, the telnet client
receives: 255, 251, 91 as it should.

Whenever the server runs in a Linux environment, the telnet client
receives: 195, 191, 195, 187, 91. Only the MXP code (91) is correct.

Does Linux filter out the IAC and WILL at some mysterious level?

I can totally reproduce this. It happens every time. It makes NO
SENSE!

Anyone curious to see this in action can telnet to coffeemud.homeip.net
port 23.

Thanks for any clues,
Bo Zimmerman

Grant Edwards

unread,
Jan 4, 2005, 3:52:24 PM1/4/05
to
On 2005-01-04, commie <b...@zimmers.net> wrote:

> Whenever the server runs in a Linux environment, the telnet client
> receives: 195, 191, 195, 187, 91. Only the MXP code (91) is correct.
>
> Does Linux filter out the IAC and WILL at some mysterious level?

Of course not. I've a number of different telnet clients and
servers under Linux -- they all worked fine.

--
Grant Edwards grante Yow! I don't understand
at the HUMOUR of the THREE
visi.com STOOGES!!

Jan Kandziora

unread,
Jan 4, 2005, 3:58:49 PM1/4/05
to
commie schrieb:

> I've written a mud (telnet server) in Java.
>
----Snip----

>
> Does Linux filter out the IAC and WILL at some mysterious level?
>
Without a code snippet, it's hard to make any helpful suggestion.


> I can totally reproduce this. It happens every time. It makes NO
> SENSE!
>

If you can reproduce it, it have to make sense. In contrary, it's hard to
track down bugs that do not happen every time.

--
Jan

Jonathan Bartlett

unread,
Jan 4, 2005, 2:57:50 PM1/4/05
to
commie wrote:
> Hello everyone. I certainly hope someone can help me here.
>
> I've written a mud (telnet server) in Java.
>
> The client I am using for testing is a simple app that connects to the
> mud server on the proper port and displays the decimal values of the
> first 30 bytes sent out by the server.
>
> When a connection is received by the server, the first data it sends
> are some telnet negotiation data, which happens to be the following in
> decimal:
> 255(IAC) 251(WILL) 91(MXP)
>
> Whenever the server runs in a Windows environment, the telnet client
> receives: 255, 251, 91 as it should.
>
> Whenever the server runs in a Linux environment, the telnet client
> receives: 195, 191, 195, 187, 91. Only the MXP code (91) is correct.

Might it be translating the codes into UTF-8 or something? Just a
thought. What function are you using to read the data?

Also, have you tried this with multiple Java implementations?

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

Kasper Dupont

unread,
Jan 4, 2005, 4:13:31 PM1/4/05
to
commie wrote:
>
> Whenever the server runs in a Linux environment, the telnet client
> receives: 195, 191, 195, 187, 91. Only the MXP code (91) is correct.

What does the code for sending this look like?
Sounds like at some point a conversion from
iso-8859-1 to utf-8 happens.

--
Kasper Dupont

Måns Rullgård

unread,
Jan 4, 2005, 4:30:28 PM1/4/05
to
"commie" <b...@zimmers.net> writes:

Something is interpreting your data as iso-8859-1 encoded characters
and converting them to utf-8. How are you sending this data? Make
sure it is NEVER seen as a Java String. Only use byte[] arrays for
special data, and you should be safe. Also remember to escape
anything that might otherwise be mistaken for a telnet command.

--
Måns Rullgård
m...@inprovide.com

commie

unread,
Jan 4, 2005, 5:58:19 PM1/4/05
to
Wow.. I had no idea there would be such quick and helpful response.
Here is a code snippet.

out = new PrintWriter(sock.getOutputStream());
in = new BufferedReader(new
InputStreamReader(sock.getInputStream()));

char[] mxpWill={TELNET_IAC,TELNET_WILL,TELNET_MXP};
out.write(mxpWill);
out.flush();
out.println("");
out.flush();

Kasper Dupont

unread,
Jan 4, 2005, 6:15:08 PM1/4/05
to

I'm no java expert, so it is not obvious to me
from above code if it should work or not. What
is important here is, that the data you send
must be treated as binary data, not text. You
should take a look on Måns' reply, which
suggests you use byte[] instead of char[]. BTW
where are all those TELNET_* macros defined?

--
Kasper Dupont

Tauno Voipio

unread,
Jan 5, 2005, 4:52:26 AM1/5/05
to

You should send a bare byte array to the socket,
the char array makes Java assume you're sending
text and converts the Unicode characters used
internally in Java into an external character
set (ISO-8859-1?).

--

Tauno Voipio
tauno voipio (at) iki fi

Måns Rullgård

unread,
Jan 5, 2005, 5:16:51 AM1/5/05
to
Tauno Voipio <tauno....@iki.fi.NOSPAM.invalid> writes:

The OP's data is being converted from iso-8859-1 to utf-8. Most
likely, his distribution uses utf-8 as the default character
encoding.

--
Måns Rullgård
m...@inprovide.com

commie

unread,
Jan 6, 2005, 3:12:19 AM1/6/05
to
Here is the relevant code.

First the writer.. notice it's been a bit "re-done" to reflect replies:

public static final int TELNET_MXP=91;
public static final int TELNET_SE=240;
public static final int TELNET_WILL=251;
public static final int TELNET_WONT=252;
public static final int TELNET_DO=253;
public static final int TELNET_DONT=254;
public static final int TELNET_IAC=255;

OutputStream raw=sock.getOutputStream();
raw.write(TELNET_IAC);
raw.write(TELNET_WILL);
raw.write(TELNET_MXP);
raw.flush();

out = new PrintWriter(new
OutputStreamWriter(sock.getOutputStream(),"iso-8859-1"));
in = new BufferedReader(new
InputStreamReader(sock.getInputStream(),"iso-8859-1"));
....
proceeds from here on out with out.printlns and so forth...

* And now for the reader:

// first the linux box
try{
Socket S=new Socket("192.168.1.103",23);
BufferedReader in=new BufferedReader(new
InputStreamReader(S.getInputStream()));
PrintWriter out=new PrintWriter(S.getOutputStream());

S.setSoTimeout(5000);
for(int i=0;i<30;i++)
{
int c=in.read();
System.out.print("("+((int)c)+") ");
}
}
catch(Exception e){}
// next the windows box
System.out.print("\n\r\n\r-----------------101-5555:");
try{
Socket S=new Socket("192.168.1.101",5555);
BufferedReader in=new BufferedReader(new
InputStreamReader(S.getInputStream()));
PrintWriter out=new PrintWriter(S.getOutputStream());

S.setSoTimeout(5000);
for(int i=0;i<30;i++)
{
int c=in.read();
System.out.print("("+((int)c)+") ");
}
}
catch(Exception e){}

** Now the output:
I run two of the servers, one of the Windows box, one on the Linux box.
When running my reader from the Windows box, BOTH client checks return:
255, 251, 91... as it should.
When running my reader from the Linux box, BOTH client checks return:
91... skipping the 255, 251 altogether.

The important part, however, is that my professional client ZMUD from
ZuggSoft, which never had any problems receiving and replying to those
telnet codes when I was running the server on the Windows Box (and
still has no trouble with the Windows server), now just spits out
graphics characters at the intro.. apparantly not receiving the proper
values.

I'm about to give up. :( Any help is appreciated.

- Bo

Jan Kandziora

unread,
Jan 6, 2005, 3:40:02 AM1/6/05
to
commie schrieb:

>
> ** Now the output:
> I run two of the servers, one of the Windows box, one on the Linux box.
> When running my reader from the Windows box, BOTH client checks return:
> 255, 251, 91... as it should.
> When running my reader from the Linux box, BOTH client checks return:
> 91... skipping the 255, 251 altogether.
>
----Snip----

>
> I'm about to give up. :( Any help is appreciated.
>
Another "idea": Normally, telnetd is run by inetd or xinetd on linux. How
have you set up your environment?

Have you deactivated the (x)inetd telnet service and run your application
standalone, or do you use (x)inetd? AFAIK the latter case does some
mangling on the data.

--
Jan

Måns Rullgård

unread,
Jan 6, 2005, 4:04:15 AM1/6/05
to
"commie" <b...@zimmers.net> writes:

> Here is the relevant code.
>
> First the writer.. notice it's been a bit "re-done" to reflect replies:
>
> public static final int TELNET_MXP=91;
> public static final int TELNET_SE=240;
> public static final int TELNET_WILL=251;
> public static final int TELNET_WONT=252;
> public static final int TELNET_DO=253;
> public static final int TELNET_DONT=254;
> public static final int TELNET_IAC=255;
>
> OutputStream raw=sock.getOutputStream();
> raw.write(TELNET_IAC);
> raw.write(TELNET_WILL);
> raw.write(TELNET_MXP);
> raw.flush();

This should work.

> out = new PrintWriter(new
> OutputStreamWriter(sock.getOutputStream(),"iso-8859-1"));
> in = new BufferedReader(new
> InputStreamReader(sock.getInputStream(),"iso-8859-1"));

Hard-coding a character encoding is generally a bad idea, though this
one is not the cause of your problem.

> proceeds from here on out with out.printlns and so forth...
>
> * And now for the reader:
>
> // first the linux box
> try{
> Socket S=new Socket("192.168.1.103",23);
> BufferedReader in=new BufferedReader(new
> InputStreamReader(S.getInputStream()));

The InputStreamReader is the problem.

> PrintWriter out=new PrintWriter(S.getOutputStream());
>
> S.setSoTimeout(5000);
> for(int i=0;i<30;i++)
> {
> int c=in.read();
> System.out.print("("+((int)c)+") ");
> }
> }
> catch(Exception e){}
>
> ** Now the output:
> I run two of the servers, one of the Windows box, one on the Linux box.
> When running my reader from the Windows box, BOTH client checks return:
> 255, 251, 91... as it should.
> When running my reader from the Linux box, BOTH client checks return:
> 91... skipping the 255, 251 altogether.

On your Linux machine, the InputStreamReader is interpreting incoming
bytes as utf-8 data, and converting to Java characters. 255 251 is an
illegal utf-8 sequence, and is silently skipped.

On (English) Windows, it appears that iso-8859-1 is used, and one byte
is exactly one character, so all the bytes are legal. If you ran the
client on, for instance, a Japanese Windows version, you'd probably
see similar problems.

When dealing with non-text data in Java, it is important to ensure
that it NEVER, EVER gets stored as a char or String. Use only byte
and byte[] arrays.

--
Måns Rullgård
m...@inprovide.com

Måns Rullgård

unread,
Jan 6, 2005, 4:27:38 AM1/6/05
to
Jan Kandziora <j...@gmx.de> writes:

If your (x)inetd mangles data, it is badly broken.

--
Måns Rullgård
m...@inprovide.com

Jan Kandziora

unread,
Jan 6, 2005, 4:36:13 AM1/6/05
to
Måns Rullgård schrieb:

>>
>> Have you deactivated the (x)inetd telnet service and run your application
>> standalone, or do you use (x)inetd? AFAIK the latter case does some
>> mangling on the data.
>
> If your (x)inetd mangles data, it is badly broken.
>
You are right. But at least now I know again the difference was in handling
pipe vs. sockets, so it has slightly different buffering behaviour.

--
Jan

Timo Voipio

unread,
Jan 9, 2005, 5:34:20 AM1/9/05
to
commie wrote:

> out = new PrintWriter(sock.getOutputStream());
> in = new BufferedReader(new
> InputStreamReader(sock.getInputStream()));

> char[] mxpWill={TELNET_IAC,TELNET_WILL,TELNET_MXP};
> out.write(mxpWill);
> out.flush();
> out.println("");
> out.flush();

If you need the character streams for some reason, you could try this:

outS = sock.getOutputStream();
out = new PrintWriter(outS);
inS = sock.getInputStream();
in = new BufferedReader(new InputStreamReader(inS));

byte[] mxpWill = {TELNET_IAC, TELNET_WILL, TELNET_MXP};
outS.write(mxpWill);
outS.flush();

I don't offer any guarantees... but trying that wouldn't hurt, would it?

--
Timo Voipio | Helsinki, Finland | ICBM at: 60 11.800 N 024 52.760 E
GeekCode ver 3: GU>CC d s-: a--- C++ UL(+)$>+++$ P+>+++ L++(+) E- W++ N++
o? K? w O M- V- PS PE Y+ PGP+ t 5++ X R tv- b++(++++) DI+ D G e- h! r !y
Remove +newsharvested to e-mail me | Poista +newsharvested jos meilaat

0 new messages