Problem with socket communication for client (On handheld) / server (on PC) application

J

jd_ie

Hi,

Sorry, I'm reposting this as unfortunately, it's quite urgent, and I
hope someone out there can help...

have a client application running on a windows ce .net device, and a
server application running on a PC. I have been experiencing problems
with the tcp connection dropping (ObjectDisposedException for the
NetworkStream) and so I have tried to cut the applications down to
their minimal details, so that I can post them and ask for your opinion
on the problem.

The client sends commands to the server, and the server sends a
response. The tcp connection is opened at the start of the
communication, and is kept open between commands - i.e. a new
connection is not opened each time a command is to be sent.

I have now configured the client, when the button on the main form is
clicked, to send a command (just a longish string) to the server. When
the server receives a command, it sends the response (just another
arbitrary string in this example). I have used a loop on the client
side to send the same command up to 500 times. At about iteration 70, I
get an ObjectDisposedException, and the server reports that the
connection was closed on the client side.

Now an error occurring every 70 times may not seem that often, but in
the real application, I am scanning a barcode, and on the basis of
that, running stored procedures on the server, and the amount of data
going back and forth is more than in this example. I am getting an
error every second scan or so, which is definitely not acceptable. I
am assuming that if I can solve the problem in this simple example
application, then the (hopefully exact same) problem in my actual
application will also be solved.

The exceptions happen both when the client handheld is connected to the
PC via activesync, and the local lan ip is used to connect to the
server, OR if the client handheld is connected via a wireless lan
access point when NOT connected via activesync. Sometimes an
IOException occurs instead of the ObjectDisposedException. But an
exception occurs without fail, after some iteration of the loop.

The same happens when using the emulator.

An important point is if I make a PC client application, using the same
code as the handheld client application, is successfully sends and
receives the 500 commands and responses, whereas the handheld and
emulator only make it to about 70. The code is below, I'd appreciate
any help, I have no idea why this is happening!

I thought that maybe it would have something to do with a memory
problem, but I'm not sure if this is the case. I have tried running
GC.Collect() after each iteration, but this just makes the exception
happen immediately.

Thanks,
Jonathan

CLIENT

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace WinPDA
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class FormUserSignIn : System.Windows.Forms.Form
{
private System.Windows.Forms.Label lblReceivedData;
private System.Windows.Forms.Button cmdSendData2;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button cmdSendData;

public FormUserSignIn()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>

static void Main()
{
Application.Run(new FormUserSignIn());
}

NetworkStream ApplicationStream = null;

public void FormUserSignIn_Load(object sender, System.EventArgs
e)
{
GlobalData.refFormUserSignIn = this;


}


private void cmdSendData_Click(object sender, System.EventArgs
e)
{
// Connect to server
ApplicationStream = EstablishConnection();

byte[] bytesToSend = new byte[256];
int iBufferLength = 8096;
byte[] buffer = new byte[iBufferLength];

string strResult = "";
bool bReceivedResponse = false;
int numBytesRead = 0;
int i = 0, j = 0;

for (j = 0; j < 500; j++)
{
// Send command
bytesToSend = ASCIIEncoding.ASCII.GetBytes("This a test
command: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\0");

try
{
ApplicationStream.Write(bytesToSend, 0,
bytesToSend.Length);
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException occurred
writing to stream");
return;
}
catch (Exception)
{
MessageBox.Show("Exception occurred writing to
stream");
return;
}

// Get result
strResult = "";
bReceivedResponse = false;
numBytesRead = 0;

do
{
//for (i = 0; i < iBufferLength; i++)
//{
// bufferIdea = Convert.ToByte(' ');
//}

try
{
numBytesRead = ApplicationStream.Read(buffer,
0, iBufferLength);
}
catch (IOException)
{
MessageBox.Show("IOException occurred reading
from stream");
return;
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException
occurred reading from stream");
return;
}

if (numBytesRead > 0)
{
// Convert and add to input string
strResult +=
ASCIIEncoding.ASCII.GetString(buffer, 0, numBytesRead);

if (strResult.IndexOf("\0") != -1)
{
// Finished reading response successfully
strResult = strResult.Substring(0,
strResult.Length - 1);
bReceivedResponse = true;
break;
}
}
}
while (numBytesRead > 0);

Cursor.Current = Cursors.Default;
if (bReceivedResponse)
{
lblReceivedData.Text = strResult;
}
else
{
lblReceivedData.Text = "No data";
}

// Pause
//ApplicationStream.Flush();
//System.Threading.Thread.Sleep(50);
}
}

public NetworkStream EstablishConnection()
{
TcpClient client = new TcpClient();
IPEndPoint ipendpoint = new
IPEndPoint(IPAddress.Parse(Utilities.GetAppSetting("ServerIPAddress")),
GlobalData.SERVER_PORT);

try
{
client.Connect(ipendpoint);
}
catch (Exception)
{
// Connection failed
client.Close();
return null;
}

// Connection successful
return client.GetStream();
}
}
}


SERVER

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.IO;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace WinPDAServer
{
//-----------------------------------------
// Get a file name from the client.
// Open the file and send the contents from
// the server to the client
//-----------------------------------------
public class Server : IDisposable
{
private FormMain mainForm;
private Socket socketForClient;
private TcpListener tcpListener;
private static ArrayList clientList = new ArrayList();



public Server(FormMain mainForm)
{
this.mainForm = mainForm;
}



public void Run()
{
tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"),
6767);
//tcpListener = new
TcpListener(Dns.Resolve("localhost").AddressList[0], 6767);
tcpListener.Start();

mainForm.AddStatus("Server started. Waiting for connection
on port 6767.");

// Wait for clients
while (true)
{
// For each client connection, pass the client to a new
thread and
// return immediately to listening for the next client
try
{
socketForClient = tcpListener.AcceptSocket();
}
catch (SocketException)
{

}

if (socketForClient.Connected)
{
ClientHandler handler = new
ClientHandler(socketForClient, mainForm);
clientList.Add(handler);

mainForm.AddStatus("");
mainForm.AddStatus("Client connected");
handler.StartRead();
}
}
}



/// <summary>
/// Clean up before object is destroyed
/// </summary>
public void Dispose()
{
if (socketForClient != null)
{
socketForClient.Close();
}

if (tcpListener != null)
{
tcpListener.Stop();
}
}



/// <summary>
/// Nested ClientHandler class. Each instance handles one
client
/// </summary>
public class ClientHandler : IDisposable
{
private const int BufferSize = 1024;
private byte[] buffer;
private Socket socket;
private NetworkStream networkStream;
private AsyncCallback readCommandCallback;
private FormMain mainForm;

private string dateTimeConnected;
private string dateConnected;
private string strRead;


public ClientHandler(Socket socketForClient, FormMain
mainForm)
{
this.mainForm = mainForm;
this.socket = socketForClient;
networkStream = new NetworkStream(socketForClient);
buffer = new byte[BufferSize];

// Set callbacks
readCommandCallback = new
AsyncCallback(this.OnReadCommandComplete);

dateTimeConnected = DateTime.Now.ToString("yyyy-MM-dd
HH-mm-ss");
dateConnected = DateTime.Now.ToString("yyyy-MM-dd");
}



public void StartRead()
{
strRead = "";
networkStream.BeginRead(buffer, 0, buffer.Length,
readCommandCallback, null);
}



private void OnReadCommandComplete(IAsyncResult ar)
{
int bytesRead = 0;

try
{
bytesRead = networkStream.EndRead(ar);
}
catch (Exception)
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}

if (bytesRead > 0)
{
strRead += Encoding.ASCII.GetString(buffer, 0,
bytesRead);

if (strRead.IndexOf("\0") != -1)
{
// Have read entire string, so save it and read
the file contents
string strCommandString = strRead.Substring(0,
strRead.Length - 1);
mainForm.AddStatus("Received command: " +
strCommandString + "...");

string strResponse = "This is a test command
response: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\0";

networkStream.Write(ASCIIEncoding.ASCII.GetBytes(strResponse), 0,
strResponse.Length);

// Response has been sent, so wait for next
command
strRead = "";
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
}
else
{
// Have not read whole string, so read rest of
it
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
return;
}
}
else
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}
}



/// <summary>
/// Release resources before object is destroyed
/// </summary>
public void Dispose()
{
if (networkStream != null) networkStream.Close();
if (socket != null) socket.Close();
networkStream = null;
socket = null;

// Remove client from array list
clientList.Remove(this);
}

}

}
}
 
P

Paul G. Tobey [eMVP]

I'm sure that everyone thinks that their question is just as urgent as you
think that yours is. Don't start new threads for *that* reason. A new
thread should only be started for a new question...

OK, and so you've run this program in the debugger and, when the object
disposed exception is thrown, what operation is the code doing or is it
internal to one of the classes? And why would you do this network I/O in
direct response to a user interface message? Won't that completely lock up
the UI for a significant period of time? I also note that your code doesn't
match the communication scheme that you indicate is supposed to be going on
(command/response, command/response, command/response). Why not?

Paul T.

jd_ie said:
Hi,

Sorry, I'm reposting this as unfortunately, it's quite urgent, and I
hope someone out there can help...

have a client application running on a windows ce .net device, and a
server application running on a PC. I have been experiencing problems
with the tcp connection dropping (ObjectDisposedException for the
NetworkStream) and so I have tried to cut the applications down to
their minimal details, so that I can post them and ask for your opinion
on the problem.

The client sends commands to the server, and the server sends a
response. The tcp connection is opened at the start of the
communication, and is kept open between commands - i.e. a new
connection is not opened each time a command is to be sent.

I have now configured the client, when the button on the main form is
clicked, to send a command (just a longish string) to the server. When
the server receives a command, it sends the response (just another
arbitrary string in this example). I have used a loop on the client
side to send the same command up to 500 times. At about iteration 70, I
get an ObjectDisposedException, and the server reports that the
connection was closed on the client side.

Now an error occurring every 70 times may not seem that often, but in
the real application, I am scanning a barcode, and on the basis of
that, running stored procedures on the server, and the amount of data
going back and forth is more than in this example. I am getting an
error every second scan or so, which is definitely not acceptable. I
am assuming that if I can solve the problem in this simple example
application, then the (hopefully exact same) problem in my actual
application will also be solved.

The exceptions happen both when the client handheld is connected to the
PC via activesync, and the local lan ip is used to connect to the
server, OR if the client handheld is connected via a wireless lan
access point when NOT connected via activesync. Sometimes an
IOException occurs instead of the ObjectDisposedException. But an
exception occurs without fail, after some iteration of the loop.

The same happens when using the emulator.

An important point is if I make a PC client application, using the same
code as the handheld client application, is successfully sends and
receives the 500 commands and responses, whereas the handheld and
emulator only make it to about 70. The code is below, I'd appreciate
any help, I have no idea why this is happening!

I thought that maybe it would have something to do with a memory
problem, but I'm not sure if this is the case. I have tried running
GC.Collect() after each iteration, but this just makes the exception
happen immediately.

Thanks,
Jonathan

CLIENT

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace WinPDA
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class FormUserSignIn : System.Windows.Forms.Form
{
private System.Windows.Forms.Label lblReceivedData;
private System.Windows.Forms.Button cmdSendData2;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button cmdSendData;

public FormUserSignIn()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>

static void Main()
{
Application.Run(new FormUserSignIn());
}

NetworkStream ApplicationStream = null;

public void FormUserSignIn_Load(object sender, System.EventArgs
e)
{
GlobalData.refFormUserSignIn = this;


}


private void cmdSendData_Click(object sender, System.EventArgs
e)
{
// Connect to server
ApplicationStream = EstablishConnection();

byte[] bytesToSend = new byte[256];
int iBufferLength = 8096;
byte[] buffer = new byte[iBufferLength];

string strResult = "";
bool bReceivedResponse = false;
int numBytesRead = 0;
int i = 0, j = 0;

for (j = 0; j < 500; j++)
{
// Send command
bytesToSend = ASCIIEncoding.ASCII.GetBytes("This a test
command: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\0");

try
{
ApplicationStream.Write(bytesToSend, 0,
bytesToSend.Length);
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException occurred
writing to stream");
return;
}
catch (Exception)
{
MessageBox.Show("Exception occurred writing to
stream");
return;
}

// Get result
strResult = "";
bReceivedResponse = false;
numBytesRead = 0;

do
{
//for (i = 0; i < iBufferLength; i++)
//{
// bufferIdea = Convert.ToByte(' ');
//}

try
{
numBytesRead = ApplicationStream.Read(buffer,
0, iBufferLength);
}
catch (IOException)
{
MessageBox.Show("IOException occurred reading
from stream");
return;
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException
occurred reading from stream");
return;
}

if (numBytesRead > 0)
{
// Convert and add to input string
strResult +=
ASCIIEncoding.ASCII.GetString(buffer, 0, numBytesRead);

if (strResult.IndexOf("\0") != -1)
{
// Finished reading response successfully
strResult = strResult.Substring(0,
strResult.Length - 1);
bReceivedResponse = true;
break;
}
}
}
while (numBytesRead > 0);

Cursor.Current = Cursors.Default;
if (bReceivedResponse)
{
lblReceivedData.Text = strResult;
}
else
{
lblReceivedData.Text = "No data";
}

// Pause
//ApplicationStream.Flush();
//System.Threading.Thread.Sleep(50);
}
}

public NetworkStream EstablishConnection()
{
TcpClient client = new TcpClient();
IPEndPoint ipendpoint = new
IPEndPoint(IPAddress.Parse(Utilities.GetAppSetting("ServerIPAddress")),
GlobalData.SERVER_PORT);

try
{
client.Connect(ipendpoint);
}
catch (Exception)
{
// Connection failed
client.Close();
return null;
}

// Connection successful
return client.GetStream();
}
}
}


SERVER

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.IO;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace WinPDAServer
{
//-----------------------------------------
// Get a file name from the client.
// Open the file and send the contents from
// the server to the client
//-----------------------------------------
public class Server : IDisposable
{
private FormMain mainForm;
private Socket socketForClient;
private TcpListener tcpListener;
private static ArrayList clientList = new ArrayList();



public Server(FormMain mainForm)
{
this.mainForm = mainForm;
}



public void Run()
{
tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"),
6767);
//tcpListener = new
TcpListener(Dns.Resolve("localhost").AddressList[0], 6767);
tcpListener.Start();

mainForm.AddStatus("Server started. Waiting for connection
on port 6767.");

// Wait for clients
while (true)
{
// For each client connection, pass the client to a new
thread and
// return immediately to listening for the next client
try
{
socketForClient = tcpListener.AcceptSocket();
}
catch (SocketException)
{

}

if (socketForClient.Connected)
{
ClientHandler handler = new
ClientHandler(socketForClient, mainForm);
clientList.Add(handler);

mainForm.AddStatus("");
mainForm.AddStatus("Client connected");
handler.StartRead();
}
}
}



/// <summary>
/// Clean up before object is destroyed
/// </summary>
public void Dispose()
{
if (socketForClient != null)
{
socketForClient.Close();
}

if (tcpListener != null)
{
tcpListener.Stop();
}
}



/// <summary>
/// Nested ClientHandler class. Each instance handles one
client
/// </summary>
public class ClientHandler : IDisposable
{
private const int BufferSize = 1024;
private byte[] buffer;
private Socket socket;
private NetworkStream networkStream;
private AsyncCallback readCommandCallback;
private FormMain mainForm;

private string dateTimeConnected;
private string dateConnected;
private string strRead;


public ClientHandler(Socket socketForClient, FormMain
mainForm)
{
this.mainForm = mainForm;
this.socket = socketForClient;
networkStream = new NetworkStream(socketForClient);
buffer = new byte[BufferSize];

// Set callbacks
readCommandCallback = new
AsyncCallback(this.OnReadCommandComplete);

dateTimeConnected = DateTime.Now.ToString("yyyy-MM-dd
HH-mm-ss");
dateConnected = DateTime.Now.ToString("yyyy-MM-dd");
}



public void StartRead()
{
strRead = "";
networkStream.BeginRead(buffer, 0, buffer.Length,
readCommandCallback, null);
}



private void OnReadCommandComplete(IAsyncResult ar)
{
int bytesRead = 0;

try
{
bytesRead = networkStream.EndRead(ar);
}
catch (Exception)
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}

if (bytesRead > 0)
{
strRead += Encoding.ASCII.GetString(buffer, 0,
bytesRead);

if (strRead.IndexOf("\0") != -1)
{
// Have read entire string, so save it and read
the file contents
string strCommandString = strRead.Substring(0,
strRead.Length - 1);
mainForm.AddStatus("Received command: " +
strCommandString + "...");

string strResponse = "This is a test command
response: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\0";

networkStream.Write(ASCIIEncoding.ASCII.GetBytes(strResponse), 0,
strResponse.Length);

// Response has been sent, so wait for next
command
strRead = "";
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
}
else
{
// Have not read whole string, so read rest of
it
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
return;
}
}
else
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}
}



/// <summary>
/// Release resources before object is destroyed
/// </summary>
public void Dispose()
{
if (networkStream != null) networkStream.Close();
if (socket != null) socket.Close();
networkStream = null;
socket = null;

// Remove client from array list
clientList.Remove(this);
}

}

}
}
 
J

jd_ie

Apologies Paul.

I got a response on another forum which seems to have solved it. The
problem was that I declared the TCPClient in a function, rather than in
the form, and it was being disposed after a certain amount of time.

Thanks for responding, I appreciate it.
I'm sure that everyone thinks that their question is just as urgent as you
think that yours is. Don't start new threads for *that* reason. A new
thread should only be started for a new question...

OK, and so you've run this program in the debugger and, when the object
disposed exception is thrown, what operation is the code doing or is it
internal to one of the classes? And why would you do this network I/O in
direct response to a user interface message? Won't that completely lock up
the UI for a significant period of time? I also note that your code doesn't
match the communication scheme that you indicate is supposed to be going on
(command/response, command/response, command/response). Why not?

Paul T.

jd_ie said:
Hi,

Sorry, I'm reposting this as unfortunately, it's quite urgent, and I
hope someone out there can help...

have a client application running on a windows ce .net device, and a
server application running on a PC. I have been experiencing problems
with the tcp connection dropping (ObjectDisposedException for the
NetworkStream) and so I have tried to cut the applications down to
their minimal details, so that I can post them and ask for your opinion
on the problem.

The client sends commands to the server, and the server sends a
response. The tcp connection is opened at the start of the
communication, and is kept open between commands - i.e. a new
connection is not opened each time a command is to be sent.

I have now configured the client, when the button on the main form is
clicked, to send a command (just a longish string) to the server. When
the server receives a command, it sends the response (just another
arbitrary string in this example). I have used a loop on the client
side to send the same command up to 500 times. At about iteration 70, I
get an ObjectDisposedException, and the server reports that the
connection was closed on the client side.

Now an error occurring every 70 times may not seem that often, but in
the real application, I am scanning a barcode, and on the basis of
that, running stored procedures on the server, and the amount of data
going back and forth is more than in this example. I am getting an
error every second scan or so, which is definitely not acceptable. I
am assuming that if I can solve the problem in this simple example
application, then the (hopefully exact same) problem in my actual
application will also be solved.

The exceptions happen both when the client handheld is connected to the
PC via activesync, and the local lan ip is used to connect to the
server, OR if the client handheld is connected via a wireless lan
access point when NOT connected via activesync. Sometimes an
IOException occurs instead of the ObjectDisposedException. But an
exception occurs without fail, after some iteration of the loop.

The same happens when using the emulator.

An important point is if I make a PC client application, using the same
code as the handheld client application, is successfully sends and
receives the 500 commands and responses, whereas the handheld and
emulator only make it to about 70. The code is below, I'd appreciate
any help, I have no idea why this is happening!

I thought that maybe it would have something to do with a memory
problem, but I'm not sure if this is the case. I have tried running
GC.Collect() after each iteration, but this just makes the exception
happen immediately.

Thanks,
Jonathan

CLIENT

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace WinPDA
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class FormUserSignIn : System.Windows.Forms.Form
{
private System.Windows.Forms.Label lblReceivedData;
private System.Windows.Forms.Button cmdSendData2;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button cmdSendData;

public FormUserSignIn()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>

static void Main()
{
Application.Run(new FormUserSignIn());
}

NetworkStream ApplicationStream = null;

public void FormUserSignIn_Load(object sender, System.EventArgs
e)
{
GlobalData.refFormUserSignIn = this;


}


private void cmdSendData_Click(object sender, System.EventArgs
e)
{
// Connect to server
ApplicationStream = EstablishConnection();

byte[] bytesToSend = new byte[256];
int iBufferLength = 8096;
byte[] buffer = new byte[iBufferLength];

string strResult = "";
bool bReceivedResponse = false;
int numBytesRead = 0;
int i = 0, j = 0;

for (j = 0; j < 500; j++)
{
// Send command
bytesToSend = ASCIIEncoding.ASCII.GetBytes("This a test
command: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\0");

try
{
ApplicationStream.Write(bytesToSend, 0,
bytesToSend.Length);
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException occurred
writing to stream");
return;
}
catch (Exception)
{
MessageBox.Show("Exception occurred writing to
stream");
return;
}

// Get result
strResult = "";
bReceivedResponse = false;
numBytesRead = 0;

do
{
//for (i = 0; i < iBufferLength; i++)
//{
// bufferIdea = Convert.ToByte(' ');
//}

try
{
numBytesRead = ApplicationStream.Read(buffer,
0, iBufferLength);
}
catch (IOException)
{
MessageBox.Show("IOException occurred reading
from stream");
return;
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException
occurred reading from stream");
return;
}

if (numBytesRead > 0)
{
// Convert and add to input string
strResult +=
ASCIIEncoding.ASCII.GetString(buffer, 0, numBytesRead);

if (strResult.IndexOf("\0") != -1)
{
// Finished reading response successfully
strResult = strResult.Substring(0,
strResult.Length - 1);
bReceivedResponse = true;
break;
}
}
}
while (numBytesRead > 0);

Cursor.Current = Cursors.Default;
if (bReceivedResponse)
{
lblReceivedData.Text = strResult;
}
else
{
lblReceivedData.Text = "No data";
}

// Pause
//ApplicationStream.Flush();
//System.Threading.Thread.Sleep(50);
}
}

public NetworkStream EstablishConnection()
{
TcpClient client = new TcpClient();
IPEndPoint ipendpoint = new
IPEndPoint(IPAddress.Parse(Utilities.GetAppSetting("ServerIPAddress")),
GlobalData.SERVER_PORT);

try
{
client.Connect(ipendpoint);
}
catch (Exception)
{
// Connection failed
client.Close();
return null;
}

// Connection successful
return client.GetStream();
}
}
}


SERVER

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.IO;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace WinPDAServer
{
//-----------------------------------------
// Get a file name from the client.
// Open the file and send the contents from
// the server to the client
//-----------------------------------------
public class Server : IDisposable
{
private FormMain mainForm;
private Socket socketForClient;
private TcpListener tcpListener;
private static ArrayList clientList = new ArrayList();



public Server(FormMain mainForm)
{
this.mainForm = mainForm;
}



public void Run()
{
tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"),
6767);
//tcpListener = new
TcpListener(Dns.Resolve("localhost").AddressList[0], 6767);
tcpListener.Start();

mainForm.AddStatus("Server started. Waiting for connection
on port 6767.");

// Wait for clients
while (true)
{
// For each client connection, pass the client to a new
thread and
// return immediately to listening for the next client
try
{
socketForClient = tcpListener.AcceptSocket();
}
catch (SocketException)
{

}

if (socketForClient.Connected)
{
ClientHandler handler = new
ClientHandler(socketForClient, mainForm);
clientList.Add(handler);

mainForm.AddStatus("");
mainForm.AddStatus("Client connected");
handler.StartRead();
}
}
}



/// <summary>
/// Clean up before object is destroyed
/// </summary>
public void Dispose()
{
if (socketForClient != null)
{
socketForClient.Close();
}

if (tcpListener != null)
{
tcpListener.Stop();
}
}



/// <summary>
/// Nested ClientHandler class. Each instance handles one
client
/// </summary>
public class ClientHandler : IDisposable
{
private const int BufferSize = 1024;
private byte[] buffer;
private Socket socket;
private NetworkStream networkStream;
private AsyncCallback readCommandCallback;
private FormMain mainForm;

private string dateTimeConnected;
private string dateConnected;
private string strRead;


public ClientHandler(Socket socketForClient, FormMain
mainForm)
{
this.mainForm = mainForm;
this.socket = socketForClient;
networkStream = new NetworkStream(socketForClient);
buffer = new byte[BufferSize];

// Set callbacks
readCommandCallback = new
AsyncCallback(this.OnReadCommandComplete);

dateTimeConnected = DateTime.Now.ToString("yyyy-MM-dd
HH-mm-ss");
dateConnected = DateTime.Now.ToString("yyyy-MM-dd");
}



public void StartRead()
{
strRead = "";
networkStream.BeginRead(buffer, 0, buffer.Length,
readCommandCallback, null);
}



private void OnReadCommandComplete(IAsyncResult ar)
{
int bytesRead = 0;

try
{
bytesRead = networkStream.EndRead(ar);
}
catch (Exception)
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}

if (bytesRead > 0)
{
strRead += Encoding.ASCII.GetString(buffer, 0,
bytesRead);

if (strRead.IndexOf("\0") != -1)
{
// Have read entire string, so save it and read
the file contents
string strCommandString = strRead.Substring(0,
strRead.Length - 1);
mainForm.AddStatus("Received command: " +
strCommandString + "...");

string strResponse = "This is a test command
response: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\0";

networkStream.Write(ASCIIEncoding.ASCII.GetBytes(strResponse), 0,
strResponse.Length);

// Response has been sent, so wait for next
command
strRead = "";
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
}
else
{
// Have not read whole string, so read rest of
it
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
return;
}
}
else
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}
}



/// <summary>
/// Release resources before object is destroyed
/// </summary>
public void Dispose()
{
if (networkStream != null) networkStream.Close();
if (socket != null) socket.Close();
networkStream = null;
socket = null;

// Remove client from array list
clientList.Remove(this);
}

}

}
}
 
P

Paul G. Tobey [eMVP]

Makes sense. Glad you got it fixed.

Paul T.

jd_ie said:
Apologies Paul.

I got a response on another forum which seems to have solved it. The
problem was that I declared the TCPClient in a function, rather than in
the form, and it was being disposed after a certain amount of time.

Thanks for responding, I appreciate it.
I'm sure that everyone thinks that their question is just as urgent as
you
think that yours is. Don't start new threads for *that* reason. A new
thread should only be started for a new question...

OK, and so you've run this program in the debugger and, when the object
disposed exception is thrown, what operation is the code doing or is it
internal to one of the classes? And why would you do this network I/O in
direct response to a user interface message? Won't that completely lock
up
the UI for a significant period of time? I also note that your code
doesn't
match the communication scheme that you indicate is supposed to be going
on
(command/response, command/response, command/response). Why not?

Paul T.

jd_ie said:
Hi,

Sorry, I'm reposting this as unfortunately, it's quite urgent, and I
hope someone out there can help...

have a client application running on a windows ce .net device, and a
server application running on a PC. I have been experiencing problems
with the tcp connection dropping (ObjectDisposedException for the
NetworkStream) and so I have tried to cut the applications down to
their minimal details, so that I can post them and ask for your opinion
on the problem.

The client sends commands to the server, and the server sends a
response. The tcp connection is opened at the start of the
communication, and is kept open between commands - i.e. a new
connection is not opened each time a command is to be sent.

I have now configured the client, when the button on the main form is
clicked, to send a command (just a longish string) to the server. When
the server receives a command, it sends the response (just another
arbitrary string in this example). I have used a loop on the client
side to send the same command up to 500 times. At about iteration 70, I
get an ObjectDisposedException, and the server reports that the
connection was closed on the client side.

Now an error occurring every 70 times may not seem that often, but in
the real application, I am scanning a barcode, and on the basis of
that, running stored procedures on the server, and the amount of data
going back and forth is more than in this example. I am getting an
error every second scan or so, which is definitely not acceptable. I
am assuming that if I can solve the problem in this simple example
application, then the (hopefully exact same) problem in my actual
application will also be solved.

The exceptions happen both when the client handheld is connected to the
PC via activesync, and the local lan ip is used to connect to the
server, OR if the client handheld is connected via a wireless lan
access point when NOT connected via activesync. Sometimes an
IOException occurs instead of the ObjectDisposedException. But an
exception occurs without fail, after some iteration of the loop.

The same happens when using the emulator.

An important point is if I make a PC client application, using the same
code as the handheld client application, is successfully sends and
receives the 500 commands and responses, whereas the handheld and
emulator only make it to about 70. The code is below, I'd appreciate
any help, I have no idea why this is happening!

I thought that maybe it would have something to do with a memory
problem, but I'm not sure if this is the case. I have tried running
GC.Collect() after each iteration, but this just makes the exception
happen immediately.

Thanks,
Jonathan

CLIENT

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace WinPDA
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class FormUserSignIn : System.Windows.Forms.Form
{
private System.Windows.Forms.Label lblReceivedData;
private System.Windows.Forms.Button cmdSendData2;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button cmdSendData;

public FormUserSignIn()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>

static void Main()
{
Application.Run(new FormUserSignIn());
}

NetworkStream ApplicationStream = null;

public void FormUserSignIn_Load(object sender, System.EventArgs
e)
{
GlobalData.refFormUserSignIn = this;


}


private void cmdSendData_Click(object sender, System.EventArgs
e)
{
// Connect to server
ApplicationStream = EstablishConnection();

byte[] bytesToSend = new byte[256];
int iBufferLength = 8096;
byte[] buffer = new byte[iBufferLength];

string strResult = "";
bool bReceivedResponse = false;
int numBytesRead = 0;
int i = 0, j = 0;

for (j = 0; j < 500; j++)
{
// Send command
bytesToSend = ASCIIEncoding.ASCII.GetBytes("This a test
command: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\0");

try
{
ApplicationStream.Write(bytesToSend, 0,
bytesToSend.Length);
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException occurred
writing to stream");
return;
}
catch (Exception)
{
MessageBox.Show("Exception occurred writing to
stream");
return;
}

// Get result
strResult = "";
bReceivedResponse = false;
numBytesRead = 0;

do
{
//for (i = 0; i < iBufferLength; i++)
//{
// bufferIdea = Convert.ToByte(' ');
//}

try
{
numBytesRead = ApplicationStream.Read(buffer,
0, iBufferLength);
}
catch (IOException)
{
MessageBox.Show("IOException occurred reading
from stream");
return;
}
catch (ObjectDisposedException)
{
MessageBox.Show("ObjectDisposedException
occurred reading from stream");
return;
}

if (numBytesRead > 0)
{
// Convert and add to input string
strResult +=
ASCIIEncoding.ASCII.GetString(buffer, 0, numBytesRead);

if (strResult.IndexOf("\0") != -1)
{
// Finished reading response successfully
strResult = strResult.Substring(0,
strResult.Length - 1);
bReceivedResponse = true;
break;
}
}
}
while (numBytesRead > 0);

Cursor.Current = Cursors.Default;
if (bReceivedResponse)
{
lblReceivedData.Text = strResult;
}
else
{
lblReceivedData.Text = "No data";
}

// Pause
//ApplicationStream.Flush();
//System.Threading.Thread.Sleep(50);
}
}

public NetworkStream EstablishConnection()
{
TcpClient client = new TcpClient();
IPEndPoint ipendpoint = new
IPEndPoint(IPAddress.Parse(Utilities.GetAppSetting("ServerIPAddress")),
GlobalData.SERVER_PORT);

try
{
client.Connect(ipendpoint);
}
catch (Exception)
{
// Connection failed
client.Close();
return null;
}

// Connection successful
return client.GetStream();
}
}
}


SERVER

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.IO;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace WinPDAServer
{
//-----------------------------------------
// Get a file name from the client.
// Open the file and send the contents from
// the server to the client
//-----------------------------------------
public class Server : IDisposable
{
private FormMain mainForm;
private Socket socketForClient;
private TcpListener tcpListener;
private static ArrayList clientList = new ArrayList();



public Server(FormMain mainForm)
{
this.mainForm = mainForm;
}



public void Run()
{
tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"),
6767);
//tcpListener = new
TcpListener(Dns.Resolve("localhost").AddressList[0], 6767);
tcpListener.Start();

mainForm.AddStatus("Server started. Waiting for connection
on port 6767.");

// Wait for clients
while (true)
{
// For each client connection, pass the client to a new
thread and
// return immediately to listening for the next client
try
{
socketForClient = tcpListener.AcceptSocket();
}
catch (SocketException)
{

}

if (socketForClient.Connected)
{
ClientHandler handler = new
ClientHandler(socketForClient, mainForm);
clientList.Add(handler);

mainForm.AddStatus("");
mainForm.AddStatus("Client connected");
handler.StartRead();
}
}
}



/// <summary>
/// Clean up before object is destroyed
/// </summary>
public void Dispose()
{
if (socketForClient != null)
{
socketForClient.Close();
}

if (tcpListener != null)
{
tcpListener.Stop();
}
}



/// <summary>
/// Nested ClientHandler class. Each instance handles one
client
/// </summary>
public class ClientHandler : IDisposable
{
private const int BufferSize = 1024;
private byte[] buffer;
private Socket socket;
private NetworkStream networkStream;
private AsyncCallback readCommandCallback;
private FormMain mainForm;

private string dateTimeConnected;
private string dateConnected;
private string strRead;


public ClientHandler(Socket socketForClient, FormMain
mainForm)
{
this.mainForm = mainForm;
this.socket = socketForClient;
networkStream = new NetworkStream(socketForClient);
buffer = new byte[BufferSize];

// Set callbacks
readCommandCallback = new
AsyncCallback(this.OnReadCommandComplete);

dateTimeConnected = DateTime.Now.ToString("yyyy-MM-dd
HH-mm-ss");
dateConnected = DateTime.Now.ToString("yyyy-MM-dd");
}



public void StartRead()
{
strRead = "";
networkStream.BeginRead(buffer, 0, buffer.Length,
readCommandCallback, null);
}



private void OnReadCommandComplete(IAsyncResult ar)
{
int bytesRead = 0;

try
{
bytesRead = networkStream.EndRead(ar);
}
catch (Exception)
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}

if (bytesRead > 0)
{
strRead += Encoding.ASCII.GetString(buffer, 0,
bytesRead);

if (strRead.IndexOf("\0") != -1)
{
// Have read entire string, so save it and read
the file contents
string strCommandString = strRead.Substring(0,
strRead.Length - 1);
mainForm.AddStatus("Received command: " +
strCommandString + "...");

string strResponse = "This is a test command
response: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\0";

networkStream.Write(ASCIIEncoding.ASCII.GetBytes(strResponse), 0,
strResponse.Length);

// Response has been sent, so wait for next
command
strRead = "";
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
}
else
{
// Have not read whole string, so read rest of
it
networkStream.BeginRead(buffer, 0,
buffer.Length, readCommandCallback, null);
return;
}
}
else
{
mainForm.AddStatus("Client disconnected");
mainForm.AddStatus("");
networkStream.Close();
socket.Close();
clientList.Remove(this);
}
}



/// <summary>
/// Release resources before object is destroyed
/// </summary>
public void Dispose()
{
if (networkStream != null) networkStream.Close();
if (socket != null) socket.Close();
networkStream = null;
socket = null;

// Remove client from array list
clientList.Remove(this);
}

}

}
}
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top