Click here to Skip to main content
15,885,936 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am working with VS2008 and .NET 3.5. the server and client are both on Win7.

I have a server and a client who are using the STX/ETX protocol. The server opens a TcpListener on port xxxx and what the basic thing is that the server waits for connection to come in on that port, and once a client connects, it then scans the database according to a polling interval, runs a few queries when some data changes, and then sends a reply message to the client who connected.

All the client has to do to trigger the server to start is simply to connect. Once the client receives the message then the client is supposed to send a response packet that is STX<blah blah="">ETX where <blah blah=""> is whatever the protocol info is. Just a string line, no CRLF terminator or anything. The ASCII ETX char (0x03) is the terminator.

So I have a TcpServer class written up that wraps a TcpListener the usual way, and what it does is, when a new connection is accepted it allocates a new object of a class, ServerConnection which does the following in its constructor:

C#
public ServerConnection(TcpClient client)
{
    //...

    this._thread = new Thread(OnConnection);
    this._thread.IsBackground = true;
    this._thread.Start();

    //...
}


The thread function is thus:

C#
void OnConnection()
{
    if (Connected != null)
        Connected();

    if (_client == null || _client.Connected == false)
        return;

    _stream = _client.GetStream();
    if (_stream == null)
        return; // disconnection

    while (_stream != null && _stream.CanRead)
    {
        var data = ReadData();
        OnReceive(data);
        Thread.Sleep(100);
    }

    Console.WriteLine("S: Client has disconnected.");

    if (Disconnected != null)
        Disconnected();
}


Basically, the problem is, I know the client is sending its response only once, but on the server side I am seeing the line that was sent come through twice. The ReadData() method is the usual:

C#
byte[] ReadData()
{
    lock (SyncRoot)
    {
        byte[] result = null;

        try
        {
            var bytesReceived = 0;
            var totalBytesReceived = 0;

            if (_stream == null || !_stream.CanRead)
                return result;

            if (_client.Available > 0)
            {
                result = new byte[_client.Available];
                _client.ReceiveBufferSize = _client.Available;
            }
            else
            {
                result = new byte[_defaultBufferSize];
            }

            do
            {
                if (_client.Connected)
                {
                    bytesReceived = _stream.Read(result, 0, result.Length);
                    totalBytesReceived += bytesReceived;
                }
            }
            while (_stream.DataAvailable);

            Array.Resize<byte>(ref result, totalBytesReceived);
        }
        catch (Exception exception)
        {
            Console.WriteLine("S: {0}", exception);
            result = null;
            Close();
        }
        return result;
    }
}


Lines below beginning with S: are what the server actually sends back to the client, and lines beginning with a C: are lines actually received from the client. Any other lines are just the server doing a Console.WriteLine(). The string <STX> below stands for the ASCII STX character, not the string literally. Likewise for ASCII ETX. What I get on the console is basically thus:

Listening on port 9050...
C: <new connection>
Querying database...
Forming message string...
S: <STX>messagepacket<ETX>
C: <STX>clientresponse<ETX>
C: <STX>clientresponse<ETX>


But on the client console the following is appearing (now the lines beginning with C: are lines the client sends to the server, and lines beginning with S: are lines the client receives from the server):

Connecting to server 127.0.0.1 on port 9050...
<connected>
S: <STX>messagepacket<ETX>
C: <STX>clientresponse<ETX>


So as you can see, the client socket I've developed is doing the right thing (by the way I am simulating a host system at our customer) by just sending the response once, but it shows up on the server side twice (or sometimes even three times). Do you know what I might be doing wrong?

I am thinking perhaps it's a thread synchronization issue. Thanks!
Posted
Comments
Phoenix123 8-Feb-13 4:35am    
Did you ever find a solution to this? I'm having the same problem.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900