Re: [xSocket-develop] Simple Server Sometimes Seeing Data Corruption on Client Side
Status: Inactive
Brought to you by:
grro
|
From: Gregor R. <gre...@go...> - 2008-05-04 08:13:31
|
Hi Rod,
yes, the NonBlockingConnection and BlockingConnection are not thread safe.
This means, you have to synchronize concurrent method calls. xSocket only
guarantees that the call back methods will be executed in a synchronized,
serialized manner.
The NullPointerException is caused by unsynchronized, concurrent write calls
on the same connection (-> sendMessageToAllClients will be called
concurrently) .
May be it would make sense to enhance the ConnectionUtils by a
synchronizedConnection(INonBlockingConnection nbc) and a
synchronizedConnection(IBlockingConnection con) method. But his doesn't help
if concurrent threads will execute code like:
con.markWritePosition();
con.write(..);
con.resetToWriteMark();
For this reason I'm not sure if it is a good idea to provide synchronized
connections. This will give the feeling of thread safety which fails if you
using statements like above.
I updated the tutorial by this subject
Gregor
2008/5/3 Rod Magnuson <rod...@gm...>:
> While trying to get a simple test that fails I ran into:
>
> java.lang.NullPointerException:
> Exception in thread "xServerPool-1-thread-8"
> java.lang.NullPointerException
> at org.xsocket.connection.WriteQueue.append(WriteQueue.java:133)
> at
> org.xsocket.connection.AbstractNonBlockingStream.write(AbstractNonBlockingStream.java:1060)
> at
> org.xsocket.connection.AbstractNonBlockingStream.write(AbstractNonBlockingStream.java:1040)
> at testproject.TestServer.sendMessageToAllClients(TestServer.java:73)
> at testproject.TestServer.onData(TestServer.java:63)
> at
> org.xsocket.connection.HandlerAdapter.onData(HandlerAdapter.java:132)
> at
> org.xsocket.connection.MultithreadedHandlerAdapter.access$201(MultithreadedHandlerAdapter.java:38)
> at
> org.xsocket.connection.MultithreadedHandlerAdapter$2.run(MultithreadedHandlerAdapter.java:80)
> at
> org.xsocket.SerializedTaskQueue.performPendingTasks(SerializedTaskQueue.java:113)
> at
> org.xsocket.SerializedTaskQueue.access$100(SerializedTaskQueue.java:38)
> at
> org.xsocket.SerializedTaskQueue$MultithreadedTaskProcessor.run(SerializedTaskQueue.java:139)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> at java.lang.Thread.run(Thread.java:619)
>
> Which made me think perhaps I'm lacking some basic understanding, since I
> see zero synchronization in the call chain down from connection.write. Am I
> supposed to provide this synchronization?
>
> Thanks,
> Rod
>
> Here's what my test server looks like:
>
> package testproject;
>
> import java.io.IOException;
> import java.io.UnsupportedEncodingException;
>
> import java.net.SocketTimeoutException;
>
> import java.nio.channels.ClosedChannelException;
>
> import java.util.concurrent.ConcurrentHashMap;
>
> import org.xsocket.connection.ConnectionUtils;
> import org.xsocket.connection.IConnectHandler;
> import org.xsocket.connection.IConnection;
> import org.xsocket.connection.IDataHandler;
> import org.xsocket.connection.IDisconnectHandler;
> import org.xsocket.connection.INonBlockingConnection;
> import org.xsocket.connection.Server;
>
>
> public class TestServer
> implements IConnectHandler, IDisconnectHandler, IDataHandler
> {
> public static final String END_OF_MESSAGE_DELIM = new String(new char[]
> { 0 });
> // public static final String END_OF_MESSAGE_DELIM = "\r";
>
> public static void main(String[] args)
> {
> try
> {
> final Server server = new Server(6000, new TestServer());
> server.setFlushMode(IConnection.FlushMode.ASYNC);
>
> ConnectionUtils.start(server);
> }
> catch (Exception e)
> {
> e.printStackTrace();
> }
> }
>
> public boolean onConnect(INonBlockingConnection connection)
> {
> connection.setAutoflush(false);
> m_Connections.put(connection, Boolean.TRUE);
> return true;
> }
>
> public boolean onDisconnect(INonBlockingConnection connection)
> {
> m_Connections.remove(connection);
> return true;
> }
>
> public boolean onData(INonBlockingConnection connection)
> throws IOException, UnsupportedEncodingException
> {
> // reset to read position (if former reads failed) and mark it
> connection.resetToReadMark();
> connection.markReadPosition();
>
> final String message =
> connection.readStringByDelimiter(END_OF_MESSAGE_DELIM);
>
> connection.removeReadMark();
>
> sendMessageToAllClients("<received>" + message + "</received>");
>
> return true;
> }
>
> private void sendMessageToAllClients(String message)
> throws ClosedChannelException, IOException, SocketTimeoutException
> {
> for (INonBlockingConnection connection : m_Connections.keySet())
> {
> connection.write(message + END_OF_MESSAGE_DELIM);
> connection.flush();
> }
> }
>
> private final ConcurrentHashMap<INonBlockingConnection, Boolean>
> m_Connections = new ConcurrentHashMap<INonBlockingConnection, Boolean>();
>
> }
>
>
> On Sat, May 3, 2008 at 12:43 AM, Gregor Roth <gre...@go...>
> wrote:
>
> > Hi Rod,
> >
> > would you please submit this as a bug (
> > http://sourceforge.net/tracker/?atid=850942&group_id=169583). Please
> > also add a junit test, which contains the essential xSocket-related part of
> > your client and server-side code.
> >
> > Thanks
> > Gregor
> >
> > 2008/5/3 Rod Magnuson <rod...@gm...>:
> >
> > > I've got a simple server that sends/receives null terminated Strings
> > > to/from a flash based client.
> > >
> > >
> > > Flush mode is async.
> > >
> > > I'm using the 2.0 final jar.
> > >
> > > I'm seeing times when the client is receiving mangled data. The length
> > > of the data is correct, just some of the contents are wrong. This does not
> > > happen often and is hard to reproduce. When it does happen other clients
> > > receive the correct data.
> > >
> > > I write out the messages with:
> > >
> > > String END_OF_MESSAGE_DELIM = new String(new char[] { 0 });
> > > connection.write(message + END_OF_MESSAGE_DELIM);
> > > connection.flush();
> > >
> > > It could be either client or server. Ideas on how to disqualify the
> > > server?
> > >
> > > Thanks,
> > > Rod
> > >
> > >
> > > -------------------------------------------------------------------------
> > > This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
> > > Don't miss this year's exciting event. There's still time to save
> > > $100.
> > > Use priority code J8TL2D2.
> > >
> > > http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
> > > _______________________________________________
> > > xSocket-develop mailing list
> > > xSo...@li...
> > > https://lists.sourceforge.net/lists/listinfo/xsocket-develop
> > >
> > >
> >
> >
> > -------------------------------------------------------------------------
> > This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
> > Don't miss this year's exciting event. There's still time to save $100.
> > Use priority code J8TL2D2.
> >
> > http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
> > _______________________________________________
> > xSocket-develop mailing list
> > xSo...@li...
> > https://lists.sourceforge.net/lists/listinfo/xsocket-develop
> >
> >
>
|