I am trying to learn how Thrift(version 0.9.2) works in python with a simple example. The server code works fine, but running the client code gives the error Could not connect to localhost:9090
, and I tried the shell commands
netstat -nap | grep 9090
, this outputs
tcp 0 0 0.0.35.130:9090 0.0.0.0:* LISTEN 4656/python
,
and command
nc -zv localhost 9090
which outputs
nc: connect to localhost port 9090 (tcp) failed: Connection refused
.
At this point I am not sure which part (the computer itself, Thrift, or the code?) has gone wrong. All the code is given as following, would anyone point out where the mistake is?
Below is the helloworld.thrift
:
const string HELLO_IN_KOREAN = "an-nyoung-ha-se-yo"
const string HELLO_IN_FRENCH = "bonjour!"
const string HELLO_IN_JAPANESE = "konichiwa!"
service HelloWorld {
void ping(),
i32 sayHello(),
i32 sayMsg(1:string msg)
}
and the server code is,
import sys
sys.path.append('../gen-py')
from helloworld import HelloWorld
from helloworld.ttypes import *
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
import socket
class HelloWorldHandler:
def __init__(self):
self.log = {}
def ping(self):
print "ping()"
def sayHello(self):
print "sayHello()"
return "say hello from " + socket.gethostbyname()
def sayMsg(self, msg):
print "sayMsg(" + msg + ")"
return "say " + msg + " from " + socket.gethostbyname()
handler = HelloWorldHandler()
processor = HelloWorld.Processor(handler)
transport = TSocket.TServerSocket('9090')
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print "Starting python server..."
server.serve()
print "done!"
and this is the client,
import sys
sys.path.append('../gen-py')
from helloworld import HelloWorld
from helloworld.ttypes import *
from helloworld.constants import *
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
try:
# Make socket
transport = TSocket.TSocket('localhost', 9090)
# Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport)
# Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Create a client to use the protocol encoder
client = HelloWorld.Client(protocol)
# Connect!
transport.open()
client.ping()
print "ping()"
msg = client.sayHello()
print msg
msg = client.sayMsg(HELLO_IN_KOREAN)
print msg
transport.close()
except Thrift.TException, tx:
print "%s" % (tx.message)
I think the problem is with your call -
transport = TSocket.TServerSocket('9090')
This should be
transport = TSocket.TServerSocket(host='localhost', port=9090)
or
transport = TSocket.TServerSocket(port=9090)
Actually - port
argument is not even required. If you don't give, it's default is 9090. Your code is saying host is 9090
This can be clear from the netstat -nap
output. The line indeed shows 'something' listening on port 9090 (that is because the default port in thrift TServerSocket is 9090), but check the listening address, it is 0.0.35.130
. This should be 0.0.0.0
for any interface or 127.0.0.1
for localhost
.
Edit:
In fact if you do a socket.getaddrinfo('9090', 9090)
. It does indeed show an address of 0.0.35.130
, so what you see in netstat
is not surprising.
Your nc
output is also saying nothing is listening on localhost:9090
(by the Connection Refused Error).
The above fix should fix the problem.