Jython socket typecasting problems

M

Mark Fink

I try to port a server application to Jython. At the moment I use
Jython21\Lib\socket.py
Currently I do face problems with casting the string "localhost" to the
desired value:
D:\AUT_TEST\workspace\JyFIT>jython fit/JyFitServer2.py localhost 1234
23
['fit/JyFitServer2.py', 'localhost', '1234', '23']
localhost
Traceback (innermost last):
File "fit/JyFitServer2.py", line 146, in ?
File "fit/JyFitServer2.py", line 31, in run
File "fit/JyFitServer2.py", line 96, in establishConnection
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 1st arg can't be coerced to
java.net.InetAddress or String

The cast to Integer for the port does not work either:

D:\AUT_TEST\workspace\JyFIT>jython fit/JyFitServer2.py "" 1234 23
['fit/JyFitServer2.py', '', '1234', '23']

Traceback (innermost last):
File "fit/JyFitServer2.py", line 146, in ?
File "fit/JyFitServer2.py", line 31, in run
File "fit/JyFitServer2.py", line 96, in establishConnection
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 2nd arg can't be coerced to int

This is the code section of my server class (I cut this from a Python
example):
def establishConnection(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((self.host, self.port))
Do I have to use explicit typecasting? How can this be achieved?
 
D

Diez B. Roggisch

This is the code section of my server class (I cut this from a Python
example):
def establishConnection(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((self.host, self.port))
Do I have to use explicit typecasting? How can this be achieved?

There is no such thing as explicit casting in python. You can coerce
values to values of another type - e.g. float("1.0"), and there are some
"magic" methods to support that (for that example __float__)

However, that doesn't seem to be your problem. You just pass the wrong
arguments, which makes the jython wrapping punke on you as only certain
types can be dealt with.

To me this looks as if you are supposed to do it like this:

self.socket.connect(self.host, self.port)

Note the missing parentheses.

Diez
 
D

Donn Cave

Quoth "Diez B. Roggisch" <[email protected]>:
| > This is the code section of my server class (I cut this from a Python
| > example):
| > def establishConnection(self):
| > self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
| > self.socket.connect((self.host, self.port))
| > Do I have to use explicit typecasting? How can this be achieved?
|
| There is no such thing as explicit casting in python. You can coerce
| values to values of another type - e.g. float("1.0"), and there are some
| "magic" methods to support that (for that example __float__)
|
| However, that doesn't seem to be your problem. You just pass the wrong
| arguments, which makes the jython wrapping punke on you as only certain
| types can be dealt with.
|
| To me this looks as if you are supposed to do it like this:
|
| self.socket.connect(self.host, self.port)
|
| Note the missing parentheses.

It would have been pretty easy to check that!
Traceback (most recent call last):
File "<stdin>", line 1, in ?

connect() used to support that, kind of by accident of how arguments
were parsed. 1.5.4 may have been the last version with that feature.
The documented API has always been connect(address), though.

I don't know anything about the Java problem, though. Only thing
I could suggest is to try to do as one probably does in Java, and
use a DNS function to resolve the name to an address, and then use
that address. The way Python uses (hostname, port) to represent
a internet address is convenient but hides this step of the process.
Maybe 'localhost' actually doesn't resolve on the original poster's
computer, and the implementation somehow turns this into a type issue.
If it does resolve, then maybe its IP address will work better here.

Donn Cave, (e-mail address removed)
 
K

Kent Johnson

Mark said:
The cast to Integer for the port does not work either:

D:\AUT_TEST\workspace\JyFIT>jython fit/JyFitServer2.py "" 1234 23
['fit/JyFitServer2.py', '', '1234', '23']

Traceback (innermost last):
File "fit/JyFitServer2.py", line 146, in ?
File "fit/JyFitServer2.py", line 31, in run
File "fit/JyFitServer2.py", line 96, in establishConnection
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 2nd arg can't be coerced to int

This is the code section of my server class (I cut this from a Python
example):
def establishConnection(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((self.host, self.port))
Do I have to use explicit typecasting? How can this be achieved?

This should work if you give correct arguments. For example:
Jython 2.1 on java1.4.2_06 (JIT: null)
Type "copyright", "credits" or "license" for more information.
It would be helpful to know what self.host and self.port are. Put
print type(self.host), repr(self.host)
print type(self.port), repr(self.port)

in establishConnection() to print out the values you are using.

If host.port is the command line argument it is a string and you need to
convert it to int with the int() function.
Traceback (innermost last):
File "<console>", line 1, in ?
File "C:\Downloads\Java\jython-2.1\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 1st arg can't be coerced to
java.net.InetAddress or String

Note it complains about the first arg; this may well be your error.

In general Python does not coerce argumentt types for you. Jython will
translate between Java and Python types but it won't go as far as
converting a String to an int.

Kent
 
S

Steve Holden

Diez said:
There is no such thing as explicit casting in python. You can coerce
values to values of another type - e.g. float("1.0"), and there are some
"magic" methods to support that (for that example __float__)

However, that doesn't seem to be your problem. You just pass the wrong
arguments, which makes the jython wrapping punke on you as only certain
types can be dealt with.

To me this looks as if you are supposed to do it like this:

self.socket.connect(self.host, self.port)

Note the missing parentheses.
"""connect(address)
Connect to a remote socket at address. (The format of address
depends on the address family -- see above.) Note: This method has
historically accepted a pair of parameters for AF_INET addresses instead
of only a tuple. This was never intentional and is no longer available
in Python 2.0 and later. """

So if Jython 2.1 is conformant it should indeed require a single
argument which is an (IPAddress, port) tuple.

It might be that the OP can't, for some reason associate with the local
environment, resolve "localhost" to an IP address. What happens if
"127.0.0.1" is substituted?

Irrespective of that, it does seem that the error message is at best
misleading and at most just plain wrong. There's aproject to bring
Jython up to a more recent specification, but it will take time ...

regards
Steve
 
M

Mark Fink

thanks to the help of this group I moved a tiny step forward. Obviously
it is not possible to resolve name localhost:
Type "copyright", "credits" or "license" for more information.Traceback (innermost last):
Traceback (innermost last):
Traceback (innermost last):
File "<console>", line 1, in ?
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at
java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:507)

Unfortunately this is not the solution (I tried 127.0.0.1 before my
first post).
I added the two print lines as recommended:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print type(self.host), repr(self.host)
print type(self.port), repr(self.port)
self.socket.connect((self.host, self.port))
self.socketOutput = self.socket.getOutputStream()

And more specific information:
D:\AUT_TEST\workspace\JyFIT\fit>jython JyFitServer2.py 127.0.0.1 1234
12
['JyFitServer2.py', '127.0.0.1', '1234', '12']
127.0.0.1
org.python.core.PyString '127.0.0.1'
org.python.core.PyString '1234'
Traceback (innermost last):
File "JyFitServer2.py", line 148, in ?
File "JyFitServer2.py", line 31, in run
File "JyFitServer2.py", line 98, in establishConnection
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 1st arg can't be coerced to
java.net.InetAddress or String

No casting from string to string?? I learned that there is no such
thing as explicit typecasting. What to do?
 
D

Donn Cave

thanks to the help of this group I moved a tiny step forward. Obviously
it is not possible to resolve name localhost:
Type "copyright", "credits" or "license" for more information.
Traceback (innermost last):
File "<console>", line 1, in ?
NameError: localhost

Did you mean to put 'localhost' in quotes?
Traceback (innermost last):
File "<console>", line 1, in ?
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
java.net.ConnectException: Connection refused: connect
Unfortunately this is not the solution (I tried 127.0.0.1 before my
first post).

It does seem to be the solution to the problem you asked
about, since you don't get a type error here. The problem
you report now is quite different. There is no obvious
problem with the Python code, this time - it just depends
on what you're trying to do.
I added the two print lines as recommended:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print type(self.host), repr(self.host)
print type(self.port), repr(self.port)
self.socket.connect((self.host, self.port))
self.socketOutput = self.socket.getOutputStream()

And more specific information:
D:\AUT_TEST\workspace\JyFIT\fit>jython JyFitServer2.py 127.0.0.1 1234
12
['JyFitServer2.py', '127.0.0.1', '1234', '12']
127.0.0.1
org.python.core.PyString '127.0.0.1'
org.python.core.PyString '1234'
Traceback (innermost last):
File "JyFitServer2.py", line 148, in ?
File "JyFitServer2.py", line 31, in run
File "JyFitServer2.py", line 98, in establishConnection
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 1st arg can't be coerced to
java.net.InetAddress or String

No casting from string to string?? I learned that there is no such
thing as explicit typecasting. What to do?

If I understand what you're doing there, it seems to
confirm that when this socket implementation encounters
an error in a network address, during connect(), it
raises a type error. The thing to do, therefore, is
expect TypeError, where in C Python you would expect
a socket.gaierror or socket.error (in older versions)
exception.

Donn Cave, (e-mail address removed)
 
K

Kent Johnson

Mark said:
I added the two print lines as recommended:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print type(self.host), repr(self.host)
print type(self.port), repr(self.port)
self.socket.connect((self.host, self.port))
self.socketOutput = self.socket.getOutputStream()

And more specific information:
D:\AUT_TEST\workspace\JyFIT\fit>jython JyFitServer2.py 127.0.0.1 1234
12
['JyFitServer2.py', '127.0.0.1', '1234', '12']
127.0.0.1
org.python.core.PyString '127.0.0.1'
org.python.core.PyString '1234'
Traceback (innermost last):
File "JyFitServer2.py", line 148, in ?
File "JyFitServer2.py", line 31, in run
File "JyFitServer2.py", line 98, in establishConnection
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 1st arg can't be coerced to
java.net.InetAddress or String

No casting from string to string?? I learned that there is no such
thing as explicit typecasting. What to do?

The problem is that the second arg is not an int. The second problem is
that the error message errorneously points to the first arg. See my
earlier post.

Kent
 
S

Steve Holden

Kent said:
Mark said:
I added the two print lines as recommended:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print type(self.host), repr(self.host)
print type(self.port), repr(self.port)
self.socket.connect((self.host, self.port))
self.socketOutput = self.socket.getOutputStream()

And more specific information:
D:\AUT_TEST\workspace\JyFIT\fit>jython JyFitServer2.py 127.0.0.1 1234
12
['JyFitServer2.py', '127.0.0.1', '1234', '12']
127.0.0.1
org.python.core.PyString '127.0.0.1'
org.python.core.PyString '1234'
Traceback (innermost last):
File "JyFitServer2.py", line 148, in ?
File "JyFitServer2.py", line 31, in run
File "JyFitServer2.py", line 98, in establishConnection
File "D:\AUT_TEST\Jython21\Lib\socket.py", line 135, in connect
TypeError: java.net.Socket(): 1st arg can't be coerced to
java.net.InetAddress or String

No casting from string to string?? I learned that there is no such
thing as explicit typecasting. What to do?


The problem is that the second arg is not an int. The second problem is
that the error message errorneously points to the first arg. See my
earlier post.

OK, so presumably you've worked out that where you assign

self.port = something

you need to use

self.port = int(something)

That should do it - Python doesn't have implicit type conversion like
Perl does, but there are plenty of conversion functions available. That
error message really wasn't helpful, was it?

regards
Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top