Java NIO server and Python asyncore client

Discussion in 'Python' started by foobarometer@gmail.com, Feb 5, 2013.

  1. Guest

    Can someone help answer this?
    http://stackoverflow.com/questions/14698020/java-nio-server-and-python-asyncore-client

    Blocking python client works, asyncore doesn't work.

    Server.java:


    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.channels.SelectableChannel;
    import java.nio.channels.Selector;
    import java.nio.ByteBuffer;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.Set;

    class Server
    {
    public Selector sel;
    public ServerSocketChannel ssc;
    public SocketChannel channel;
    public static void main(String[] args) throws Exception
    {
    Server s = new Server();
    s.openSocket(12000);
    s.run();
    }

    private void openSocket(int port) throws Exception
    {
    InetSocketAddress address = new InetSocketAddress("0.0.0.0", port);
    ssc = ServerSocketChannel.open();
    ssc.configureBlocking(false);
    ssc.socket().bind(address);
    sel = Selector.open();
    ssc.register(sel, SelectionKey.OP_ACCEPT);
    }

    public void run() throws Exception
    {
    while (true)
    {
    sel.select();
    Set<SelectionKey> keys = sel.selectedKeys();
    Iterator<SelectionKey> i = keys.iterator();
    while (i.hasNext())
    {
    SelectionKey key = (SelectionKey) i.next();
    i.remove();
    if (!key.isValid())
    {
    continue;
    }
    if (key.isAcceptable())
    {
    channel = ssc.accept();
    channel.configureBlocking(false);
    System.out.println("Accepted...\n");
    channel.register(sel, SelectionKey.OP_READ);
    }
    if (key.isReadable())
    {
    if (channel == key.channel())
    {
    System.out.println("Readable\n");
    ByteBuffer buffer = ByteBuffer.wrap(new byte[1024]);
    int pos = channel.read(buffer);
    buffer.flip();
    System.out.println(new String(buffer.array(), 0, pos));
    }
    }
    }
    }
    }
    }

    Asyncore Python Code:

    import socket
    import select
    import asyncore

    class Connector(asyncore.dispatcher):
    def __init__(self, host, port):
    asyncore.dispatcher.__init__(self)
    self.buffer = "hi"
    self.create_socket()
    self.connect((host, port))

    def handle_connect(self):
    print("[]---><---[]") # not called <------------------

    def handle_read(self):
    pass

    def writable(self):
    len(self.buffer) > 0

    def handle_write(self):
    sent = self.send(self.buffer)
    print("[]--->" + self.buffer[0:sent])
    self.buffer = self.buffer[sent:]

    def handle_close(self):
    print("[]...x...[]")
    self.close()


    connector = Connector("localhost", 12000, Handler())
    asyncore.loop()

    Python Blocking client:
    # Echo client program
    import socket
    import sys

    HOST = 'localhost' # The remote host
    PORT = 12000 # The same port as used by the server
    s = None
    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
    s = socket.socket(af, socktype, proto)
    print("socket")
    except OSError as msg:
    s = None
    continue
    try:
    s.connect(sa)
    print("connected")
    except OSError as msg:
    s.close()
    s = None
    continue
    break
    if s is None:
    print('could not open socket')
    sys.exit(1)
    print("Sending")
    s.sendall(bytes("Hey server", "UTF-8"))
    data = s.recv(1024)
    # s.close()
    print('Received', repr(data))
    , Feb 5, 2013
    #1
    1. Advertising

  2. dieter Guest

    writes:

    > Can someone help answer this?
    > http://stackoverflow.com/questions/14698020/java-nio-server-and-python-asyncore-client
    >
    > Blocking python client works, asyncore doesn't work.


    I fear you must tell us which Python version you are using.
    Your call to "dispatcher.create_socket" is incompatible with
    the code in Python 2.7 (it lacks parameters "family" and "type").


    Otherwise, I could not detect a problem in your code.
    I assume that "does not work" does not mean "I get an exception"
    but means "I do not get anything".

    You might need some debugging to detect the problem.

    Check "dispatcher.socket_map" after you have set up your connector.
    It should contain your connector object and this should
    be both "readable()" and "writable()".

    If this is the case, I would debug "asyncore.loop":

    "asyncore.dispatcher" treats the socket as "connected"
    as soon as it becomes either "readable" or "writable".

    Both should happen after "connect" is successful. Thus,
    I would look what goes wrong:

    * the socket does not become readable/writable

    this would proabably mean that the socket never
    gets connected, maybe because of bad parameters
    to "create_socket".

    * the channel is not properly registered

    * bad internal state
    dieter, Feb 6, 2013
    #2
    1. Advertising

  3. On Tuesday, February 5, 2013 10:09:28 AM UTC+2, wrote:
    > Can someone help answer this?
    >
    > http://stackoverflow.com/questions/14698020/java-nio-server-and-python-asyncore-client
    >
    >
    >
    > Blocking python client works, asyncore doesn't work.
    >


    There was return missing in writeable().

    Modified code::

    ----
    import socket
    import select
    import asyncore

    class Connector(asyncore.dispatcher):
    def __init__(self, host, port):
    asyncore.dispatcher.__init__(self)
    self.debug = True
    self.buffer = bytes("hi","ascii")
    self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
    print("Connector.connect(({},{}))".format(host,port))
    self.connect((host, port))

    def handle_connect(self):
    print("handle_connect()") # not called <------------------

    def handle_read(self):
    print("handle_read()")
    self.recv(4096)
    self.close()

    def writable(self):
    print("writable()")
    return len(self.buffer) > 0 # remember RETURN

    def handle_write(self):
    print("handle_write()")
    sent = self.send(self.buffer)
    print("send({})".format(self.buffer[0:sent]))
    self.buffer = self.buffer[sent:]

    def handle_close(self):
    print("handle_close()")
    self.close()

    connector = Connector("localhost", 12000) # Handler()
    print("asyncore.loop() enter")
    asyncore.loop()
    print("asyncore.loop() leave")
    ----

    BSD socket communication framework does not itself support connection indications
    on connection-oriented protocols, so asyncore "fakes" the indication by detecting
    if socket is writable. As the writable was false => no write event => no connection indication.

    asyncore usage and documentation is bad, so when using the module, read the source
    code to understand it's usage and functioning, or use other implementation eg.
    Tornado.
    Petri Heinilä, Feb 15, 2013
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Avizz
    Replies:
    3
    Views:
    13,765
    Andy Fish
    Sep 29, 2003
  2. iksrazal

    NIO with timeouts != NIO?

    iksrazal, Jun 17, 2004, in forum: Java
    Replies:
    1
    Views:
    6,231
    iksrazal
    Jun 18, 2004
  3. Chris Berg
    Replies:
    3
    Views:
    5,539
    Gordon Beaton
    Feb 25, 2005
  4. Dustin
    Replies:
    2
    Views:
    1,032
    G. S. Hayes
    Aug 9, 2004
  5. brieuc
    Replies:
    5
    Views:
    2,151
    Esmond Pitt
    Mar 20, 2007
Loading...

Share This Page