Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #38175 > unrolled thread

Java NIO server and Python asyncore client

Started byfoobarometer@gmail.com
First post2013-02-05 00:09 -0800
Last post2013-02-15 01:41 -0800
Articles 3 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Java NIO server and Python asyncore client foobarometer@gmail.com - 2013-02-05 00:09 -0800
    Re: Java NIO server and Python asyncore client dieter <dieter@handshake.de> - 2013-02-06 08:42 +0100
    Re: Java NIO server and Python asyncore client Petri Heinilä <hevi00@gmail.com> - 2013-02-15 01:41 -0800

#38175 — Java NIO server and Python asyncore client

Fromfoobarometer@gmail.com
Date2013-02-05 00:09 -0800
SubjectJava NIO server and Python asyncore client
Message-ID<ce1ca918-2bbe-440b-95eb-89dc257ffc9f@googlegroups.com>
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))

[toc] | [next] | [standalone]


#38261

Fromdieter <dieter@handshake.de>
Date2013-02-06 08:42 +0100
Message-ID<mailman.1405.1360136576.2939.python-list@python.org>
In reply to#38175
foobarometer@gmail.com 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

[toc] | [prev] | [next] | [standalone]


#38912

FromPetri Heinilä <hevi00@gmail.com>
Date2013-02-15 01:41 -0800
Message-ID<8f766ae3-1119-4c2c-a851-9fa0eb6e5472@googlegroups.com>
In reply to#38175
On Tuesday, February 5, 2013 10:09:28 AM UTC+2, foobar...@gmail.com 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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web