.net CF bug? code crashes emulator & device but runs fine in full

G

Guest

I've been having problems with Socket communication between a server application, running on a desktop machine, and a client, running on the .net CF on PocketPC. I think I've traced the problem to an underlying problem with the .net CF.

The following code runs fine on the full .net framework (I've compiled it under 2 projects, one for device app, one for full .net app); every second another "data" is recieved. When run on the emulator, it hangs after the first piece of data is recieved, and no exceptions are thrown.

Can anybody point to a problem with the code that is causing this behaviour? Is this a bug? I want to identify the error in my code if there is one...!

The application I'm developing requires reliable communication from server to client over a lengthy period of time (30mins plus). Any other ideas of how to achieve this?

The client app code follows, and is closely followed by the server code ...

thanks for listening....
Rua HM.

Client form class:
Code:
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace TCPClient_PPC
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class TCPClient_PPC : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox ServerTextBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox ResponseTextBox;
private System.Windows.Forms.MainMenu mainMenu1;

private int iPort = 5432;
private bool bAbort = false;

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

//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.ServerTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.ResponseTextBox = new System.Windows.Forms.TextBox();
//
// ServerTextBox
//
this.ServerTextBox.Location = new System.Drawing.Point(130, 16);
this.ServerTextBox.Text = "rualaptop";
//
// label1
//
this.label1.Location = new System.Drawing.Point(10, 18);
this.label1.Size = new System.Drawing.Size(112, 16);
this.label1.Text = "Server IP Address:";
//
// button1
//
this.button1.Location = new System.Drawing.Point(72, 234);
this.button1.Size = new System.Drawing.Size(104, 20);
this.button1.Text = "Connect";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// ResponseTextBox
//
this.ResponseTextBox.Location = new System.Drawing.Point(32, 50);
this.ResponseTextBox.Multiline = true;
this.ResponseTextBox.Size = new System.Drawing.Size(184, 168);
this.ResponseTextBox.Text = "";
//
// TCPClient_PPC
//
this.Controls.Add(this.ServerTextBox);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Controls.Add(this.ResponseTextBox);
this.Menu = this.mainMenu1;
this.Text = "Form1";
this.Closing += new System.ComponentModel.CancelEventHandler(this.TCPClient_PPC_Closing);
this.Load += new System.EventHandler(this.TCPClient_PPC_Load);

}
#endregion

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

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

private void button1_Click(object sender, System.EventArgs e)
{

}


private void TCPClient_PPC_Load(object sender, System.EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ConnectAndRecieve));
}

public void ConnectAndRecieve(object state)
{
// Verify that the server exists
IPHostEntry remoteHost;
try
{
remoteHost = Dns.Resolve(ServerTextBox.Text);
}
catch (SocketException sexp)
{
if (sexp.ErrorCode == 11001) // No such host is known
ResponseTextBox.Text =
String.Format("Server {0} not known", ServerTextBox.Text);
else
ResponseTextBox.Text =
String.Format("DNS lookup of {0} caused error: {1}",
ServerTextBox.Text, sexp.Message);
return;
}

// Try to connect to the server on port 695
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(remoteHost.AddressList[0].Address, iPort));

// Get the stream
Stream strm;
try
{
strm = client.GetStream();
}
catch (InvalidOperationException)
{
ResponseTextBox.Text =
String.Format("Cannot connect to server: {0}",
ServerTextBox.Text);
return;
}
catch (SocketException exc)
{
StringBuilder strB = new StringBuilder("");
strB.Append(
String.Format("Can't connect to server: {0}\r\n",
ServerTextBox.Text));
strB.Append(exc.Message + "\r\n");
strB.Append("Socket Error Code: "
+ exc.ErrorCode.ToString());
ResponseTextBox.Text = strB.ToString();
return;
}

ResponseTextBox.Text =  "Recievin'";

// Read the stream and convert it to ASCII
Byte[] inputBuffer = new Byte[16];
while (!bAbort)
{
int bytes = strm.Read(inputBuffer, 0, inputBuffer.Length);
string response =
Encoding.ASCII.GetString(inputBuffer, 0, bytes);

// Display the data
ResponseTextBox.Text += response;

// ease up
Thread.Sleep(0);
}

client.Close();
}

private void TCPClient_PPC_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
bAbort = true;
}
}
}


Server form class
Code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace TCPListener
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class TCPListenerForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

private TcpListener tcpServer = null;
private int iPort = 5432;
private System.Windows.Forms.TextBox textBox1;
private bool bAbort = false;
private string strData;

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

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 80);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(280, 160);
this.label1.TabIndex = 2;
this.label1.Text = "label1";
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 48);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(272, 20);
this.textBox1.TabIndex = 3;
this.textBox1.Text = "textBox1";
this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
//
// TCPListenerForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.label1);
this.Name = "TCPListenerForm";
this.Text = "TCPListenerForm";
this.Closing += new System.ComponentModel.CancelEventHandler(this.TCPListenerForm_Closing);
this.Load += new System.EventHandler(this.TCPListenerForm_Load);
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new TCPListenerForm());
}

private void btnListen_Click(object sender, System.EventArgs e)
{
ListenAndSend(null);
}

private void TCPListenerForm_Load(object sender, System.EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ListenAndSend));
}

public void ListenAndSend(object state)
{
String response;

try
{
tcpServer = new TcpListener(new IPEndPoint(System.Net.IPAddress.Any, iPort));
// report where we are
IPHostEntry thisHost = Dns.Resolve(Dns.GetHostName());
label1.Text = String.Format("Host {0} listening on {1}, port {2}",
thisHost.HostName, thisHost.AddressList[0].ToString(), iPort);

tcpServer.Start();

// Accept will block until someone connects
TcpClient clientConn = tcpServer.AcceptTcpClient();

label1.Text = "Sendin'";

while (!bAbort)
{
//lock(textBox1)
textBox1.Enabled = false;
if (textBox1.Text.Length > 0)
{
// Send back a message including the time
//response = textBox1.Text;
//textBox1.Text = "";
response = "data";

// Convert the string to a Byte Array and send it
Byte[] byteResponse = Encoding.ASCII.GetBytes(response.ToCharArray());
clientConn.GetStream().Write(byteResponse, 0, byteResponse.Length);
}
textBox1.Enabled = true;

label1.Text += "Sent";

//bAbort = true;
Thread.Sleep(0);
Thread.Sleep(1000);
}

clientConn.Close();
tcpServer.Stop();
clientConn.Close();
}
catch (SocketException socketError)
{
if (socketError.ErrorCode == 10048)
{
label1.Text = "Error, port in use";
}
else
{
label1.Text = "Error, " + socketError.ToString();
}
}

}

private void textBox1_TextChanged(object sender, System.EventArgs e)
{
}

private void TCPListenerForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
bAbort = true;
}
}
}
 
J

Jon Skeet [C# MVP]

Rua Haszard Morris said:
I've been having problems with Socket communication between a server
application, running on a desktop machine, and a client, running on
the .net CF on PocketPC. I think I've traced the problem to an
underlying problem with the .net CF.

The following code runs fine on the full .net framework (I've
compiled it under 2 projects, one for device app, one for full .net
app); every second another "data" is recieved. When run on the
emulator, it hangs after the first piece of data is recieved, and no
exceptions are thrown.

Can anybody point to a problem with the code that is causing this
behaviour? Is this a bug? I want to identify the error in my code if
there is one...!

The application I'm developing requires reliable communication from
server to client over a lengthy period of time (30mins plus). Any
other ideas of how to achieve this?

At least one problem you've got is that you're updating the UI from a
non-UI thread, which could well be locking things up.

See
http://www.pobox.com/~skeet/csharp/multithreading.html/#windows.forms
for more information.
 
G

Guest

Cheers - that sounds like very sage advice.

I thought I might be a bit hasty in claiming ".netCF bug"!

we'll see....
 

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