Re: [xSocket-develop] Simple Server Sometimes Seeing Data Corruption on Client Side
Status: Inactive
Brought to you by:
grro
|
From: Rod M. <rod...@gm...> - 2008-05-04 18:38:01
|
Thank you!
The tutorial update was great. Appreciate your help.
Rod
On Sun, May 4, 2008 at 1:04 AM, Gregor Roth <gre...@go...>
wrote:
> 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
>>>
>>>
>>
>
|