I'm trying to write a voting server and client, so you start the program and it displays the voting form and you can vote on various items. For the server part I've got the server running in a separate thread, but it's using a lot of CPU, how do I reduce the amount of CPU it's using?
this is my server:
Form1 main = new Form1();
try
{
IPAddress ipAd = IPAddress.Parse(main.ipAddress); //use local m/c IP address, and use the same in the client
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, 55548);
/* Start Listeneting at the specified port */
myList.Start();
while (true)
{
string message = "";
Socket s = myList.AcceptSocket();
if (main.users.Contains(s.RemoteEndPoint.ToString()) == false)
main.users.Add(s.RemoteEndPoint.ToString());
byte[] b = new byte[500];
int k = s.Receive(b);
for (int i = 0; i < k; i++)
{
message += (Convert.ToString(b[i]));
}
string[] messageArray = message.Split('/');
MessageBox.Show("help");
if (messageArray[0].CompareTo("vote") == 0)
{
if (main.votes.ContainsKey(messageArray[1]) != true) main.votes.Add(messageArray[1], 1);
else main.votes[messageArray[1]]++;
string[] temp = main.textBox1.Text.Split(' ');
int numVotes = Convert.ToInt32(temp[1]);
numVotes++;
main.textBox1.Text = temp[0] + " " + Convert.ToString(numVotes);
}
if (messageArray[0].CompareTo("start") == 0)
{
main.updateEverything();
}
if(messageArray[0].CompareTo("withdraw") == 0)
{
main.votes[messageArray[1]]--;
string[] temp = main.textBox1.Text.Split(' ');
int numVotes = Convert.ToInt32(temp[1]);
numVotes--;
main.textBox1.Text = temp[0] + " " + Convert.ToString(numVotes);
}
/* clean up */
s.Close();
myList.Stop();
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
You are using a blocking type of connection. The loop you create causes a CPU overhead because of the TcpListener.AcceptConnection(). Your solution is to accept non-blocking socket connections, which is done by receiving data from socket asynchronously.
Here's the msdn link that explains how it works.
http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx
I see you have string concatenations which basically affects performance; try using a StringBuilder - the message variable should be of type StringBuilder.
Related
I am trying to implement Bully Coordinator election algorithm. In this algorithm, Coordinator sends the alive message every 10 seconds and all the processes wait for at least 14 seconds to receive alive, if they don't receive the message within that time, they will initiate dead coordinator election.
The problem is AliveTimer (Timer3_Count) is increasing exponentially and active processes are also affecting it. I don't know why it is behaving weirdly.
When the initial coordinator is sending the Alive message then counter works perfectly but after dead coordinator election, it behaves weirdly.
else if (Received_Text.Contains("Alive:"))
{
SetText(Received_Text + "\n");
Coordinator_Alive = true;
Timer3_Counter = 0;
if (Alive_Count == 0)
{
Alive_Count++;
AliveTimer.Interval = (1 * 1000);
AliveTimer.Enabled = true;
AliveTimer.Elapsed += new System.Timers.ElapsedEventHandler(AliveTimer_Elapsed);
AliveTimer.Start();
}
}
The elapsed function is here
I think there is something wrong with my program, I tried everything.
private void AliveTimer_Elapsed(object sender, EventArgs e)
{
Timer3_Counter++;
SetTimer(Timer3_Counter.ToString());
Random rnd = new Random();
int rand_time = rnd.Next(14, 18);
if (Timer3_Counter == 14)
{
AliveTimer.Stop();
Timer3_Counter = 0;
Alive_Count = 0;
if (Coordinator_Alive == false)
{
byte[] buffer = Encoding.ASCII.GetBytes("Dead Coordinator Election: " + txName.Text);
_clientSocket.Send(buffer);
Timer4_Counter = 0;
DeadTimer.Interval = (1 * 1000);
DeadTimer.Elapsed += new System.Timers.ElapsedEventHandler(DeadTimer_Elapsed);
DeadTimer.Enabled = true;
DeadTimer.Start();
}
}
if (Coordinator_Alive == true)
Coordinator_Alive = false;
}
and the dead Coordinator election code is here
else if (Received_Text.Contains("Dead Coordinator Election:"))
{
SetCPID("");
Coordinator_Alive = false;
Alive_Count = 0;
Timer3_Counter = 0;
AliveTimer.Stop();
AliveTimer.Enabled = false;
string output = Regex.Match(Received_Text, #"\d+").Value;
SetText("Dead Coordinator Election Received from Process ID: " + output + "\n");
if (Convert.ToInt32(txName.Text) > Convert.ToInt32(output))
{
byte[] buffer = Encoding.ASCII.GetBytes("Greater Process No: " + txName.Text + " found than " + output + "\n");
_clientSocket.Send(buffer);
SetText("Our Process No: " + txName.Text + " is Greater than " + output + "\n");
Lower_Count++;
byte[] buffer1 = Encoding.ASCII.GetBytes("Dead Coordinator Election: " + txName.Text);
_clientSocket.Send(buffer1);
}
else
{
byte[] Txt_Send = Encoding.ASCII.GetBytes("Our Process No: " + txName.Text + " is less than " + output);
_clientSocket.Send(Txt_Send);
Greater_Count++;
}
}
The full code can be found here
Bully Algorithm
Note: I am using passive server just to broadcast messages from each process
I don't know what causes the problem, but I think you will be able to figure the cause quickly if you log start and stop all all methods and analyse the output.
This would help establish if:
1. As #Idle_Mind suggested, that you are adding more and more handlers
2. The time taken to execute each method creeps up
and more...
I don't know how you app is built but you can even start with Console.WriteLine or Debug.WriteLine.
I have built a C# console app that accepts TCP connections from GPS reporting devices I have. I built this app to collect that data and dump it into a SQL Server table.
Currently, I have the application working, but it has a bug I can't seem to figure out. As the GPS devices make connections, one out of random 1-10 successful connections give me an index out of range exception.
When I dump the raw data it does not look like something the device is sending me. Would any of you happen to know what is causing this? Also, once I get this application working correctly, it could be receiving up to 3-5k connections a minute, do you think this code could handle this?
This is the error I receive every so often, with the dump of misc data:
Image of error
This is my code:
namespace GPS2DB
{
class Program
{
static void Main(string[] args)
{
try
{
IPAddress ipAddress = IPAddress.Parse("10.71.150.253");
Console.WriteLine("Waiting for Tracker Connections...");
TcpListener listener = new TcpListener(ipAddress, 10000);
listener.Start();
while (true)
{
Socket client = listener.AcceptSocket();
Console.WriteLine("Connection accepted.");
var childSocketThread = new Thread(() =>
{
byte[] data = new byte[1024];
int size = client.Receive(data);
string gpsData = "";
for (int i = 0; i < size; i++)
{
Console.Write(Convert.ToChar(data[i]));
gpsData = gpsData + Convert.ToChar(data[i]);
}
string txt = gpsData;
string txt2 = (txt.Trim(new Char[] { '$', '#' }));
String[] values = txt2.Split(',');
//Console.WriteLine(txt2);
/*
Console.WriteLine("Unit ID: " + values[0]);
Console.WriteLine("Event Code: " + values[1]);
Console.WriteLine("UTC Date: " + values[2]);
Console.WriteLine("UTC Time: " + values[3]);
Console.WriteLine("Lat: " + values[4]);
Console.WriteLine("Long: " + values[5]);
Console.WriteLine("Speed: " + values[7]);
Console.WriteLine("Heading: " + values[11]);
Console.WriteLine("V+: " + values[16]);
Console.WriteLine("Cell Strength: " + values[17]);
Console.WriteLine("GPS Status: " + values[18]);
Console.WriteLine("Fuel Level: " + values[20]);
*/
//dump 2 database
string connectionString = "Data Source=DVT501;Initial Catalog=VehicleTracking;Persist Security Info=True;User ID=TABLE;Password=PASS";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("INSERT INTO Data_Dump (uid, eventCode, utcDate, utcTime, lat, long, speed, heading, voltage, cellStrength, gpsStatus, fuelLevel) VALUES (#uid, #eventCode, #utcDate, #utcTime, #lat, #long, #speed, #heading, #voltage, #cellStrength, #gpsStatus, #fuelLevel)");
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = connection;
try
{
cmd.Parameters.AddWithValue("#uid", values[0]);
cmd.Parameters.AddWithValue("#eventCode", values[1]);
cmd.Parameters.AddWithValue("#utcDate", values[2]);
cmd.Parameters.AddWithValue("#utcTime", values[3]);
cmd.Parameters.AddWithValue("#lat", values[4]);
cmd.Parameters.AddWithValue("#long", values[5]);
cmd.Parameters.AddWithValue("#speed", values[7]);
cmd.Parameters.AddWithValue("#heading", values[11]);
cmd.Parameters.AddWithValue("#voltage", values[16]);
cmd.Parameters.AddWithValue("#cellStrength", values[17]);
cmd.Parameters.AddWithValue("#gpsStatus", values[18]);
cmd.Parameters.AddWithValue("#fuelLevel", values[20]);
connection.Open();
cmd.ExecuteNonQuery();
}
catch (System.IndexOutOfRangeException e)
{
Console.WriteLine("IndexOutOfRangeException caught" + e);
Console.WriteLine(txt);
}
}
//end dump
Console.WriteLine();
client.Close();
});
childSocketThread.Start();
}
listener.Stop();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.StackTrace);
Console.ReadLine();
}
}
}
}
The error is with the incoming data, it's either a gps device that's configured to send data differently or some random tcp event. Check the port number you're using in a google search and make sure it's not reserved for something else.
This code will definitely not handle that many connections, you iterate through a byte array and convert one character at a time (use System.Text.Encoding.ASCII.GetString(byte[]) instead), you open and close a connection to the sql server within the receive block and so on. In order to handle that kind of activity you need to just read the data and put it in a bus or temp storage to be bulk processed.
You are assuming that you will read one message at a time. TCP provides a boundaryless stream of bytes. You can very well read a partial message or multiple messages.
How to deal with that depends on the format of the stream. If it is line based StreamReader.ReadLine() is a great solution.
The following method calls Ping.Send(). When I pass an invalid URL, Send() dies and an unhandled exception happens. What is the cause of this?
private void ping()
{
comboBox3.Visible = false;
listBox2.Items.Clear();
// check the url if it is null
if (string.IsNullOrEmpty(textBox1.Text) || textBox1.Text == "")
{
listBox2.Items.Add("Please use valid IP or web address!!");
comboBox3.Visible = false;
coloring_red_tab4();
}
else
{
// do the ping
coloring_green_tab4();
for (int i = 0; i < numericUpDown1.Value; i++)
{
string s;
s = textBox1.Text;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
Ping p = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
//pingexception was unhalded (if the url wrong here is the error)
PingReply r = p.Send(s, timeout, buffer, options);
// if it's true url
if (r.Status == IPStatus.Success)
{
listBox2.Items.Add("Ping to " + s.ToString() + "[" + r.Address.ToString() + "]" + " (Successful) "
+ "Bytes =" + r.Buffer.Length + " TTL=" + r.Options.Ttl + " Response delay = " + r.RoundtripTime.ToString() + " ms " + "\n");
label91.Text = r.Address.ToString();
}
else
{
// just to know the ip for the website if they block the icmp protocol
listBox2.Items.Add(r.Status);
IPAddress[] ips;
ips = Dns.GetHostAddresses(textBox1.Text);
foreach (IPAddress ip in ips)
{
label91.Text = ip.ToString();
}
}
}
}
}
The exception is unhandled because you do not handle it. Whenever you call a .Net library method, you need to check its documentation to see what exceptions it throws, and decide which, if any, you want to handle at that level of code. Here is the relevant portion of the documentation for Ping.Send(), which I am including as an image so you will be able to recognize these sections going forward:
Notice that the documentation states that a PingException can occur if
An exception was thrown while sending or receiving the ICMP messages. See the inner exception for the exact exception that was thrown.
Thus it's clear from the documentation that many errors from Ping() will be reported as thrown exceptions rather than reported by setting PingReply.Status != IPStatus.Success. So you need to modify your code to be something like the following:
public static bool TryPing(string hostNameOrAddress, out string pingStatusMessage, out string pingAddressMessage)
{
if (String.IsNullOrWhiteSpace(hostNameOrAddress))
{
pingStatusMessage = "Missing host name";
pingAddressMessage = "";
return false;
}
var data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
var buffer = Encoding.ASCII.GetBytes(data);
var timeout = 120;
using (var p = new Ping())
{
var options = new PingOptions();
options.DontFragment = true;
try
{
var r = p.Send(hostNameOrAddress, timeout, buffer, options);
if (r.Status == IPStatus.Success)
{
pingStatusMessage = "Ping to " + hostNameOrAddress.ToString() + "[" + r.Address.ToString() + "]" + " (Successful) "
+ "Bytes =" + r.Buffer.Length + " TTL=" + r.Options.Ttl + " Response delay = " + r.RoundtripTime.ToString() + " ms " + "\n";
pingAddressMessage = r.Address.ToString();
return true;
}
else
{
// just to know the ip for the website if they block the icmp protocol
pingStatusMessage = r.Status.ToString();
var ips = Dns.GetHostAddresses(hostNameOrAddress);
pingAddressMessage = String.Join(",", ips.Select(ip => ip.ToString()));
return false;
}
}
catch (PingException ex)
{
pingStatusMessage = string.Format("Error pinging {0}: {1}", hostNameOrAddress, (ex.InnerException ?? ex).Message);
pingAddressMessage = hostNameOrAddress;
return false;
}
}
}
Here I have extracted a utility method from the user interface code and also properly disposed of the Ping instance after it is no longer needed.
Then
TryPing(#"www.google.com", out pingStatusMessage, out pingAddressMessage);
Gives
Ping to www.google.com[146.115.8.83] (Successful) Bytes =32 TTL=62 Response delay = 8 ms
While
TryPing(#"www.kdjf98rglkfgjldkfjgdl;fge8org.com", out pingStatusMessage, out pingAddressMessage);
Gives
Error pinging www.kdjf98rglkfgjldkfjgdl;fge8org.com: No such host is known
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I tried searching everywhere for this question with no avail.
What I am trying to accomplish is that I enter a list of ports into a text box.
then I create a udpClient array with these ports start listening to them.
static class communicator
{
// Setting Variables
static UdpClient[] UDPreceiver;
static TcpListener[] TCPreceiver;
static IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
static bool listening = false;
// Listener function
public static void UDPstartlistening(int port)
{
// Startlistening
listening = true;
while (listening)
{
try
{
UDPreceiver[port] = new UdpClient(port); // udp server
if (UDPreceiver[port].Available > 0) // Only read if we have some data queued in buffer
{
//IPEndPoint object will allow us to read datagrams sent from any tracker.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
// Blocks untill data is received
Byte[] receiveBytes = UDPreceiver[port].Receive(ref RemoteIpEndPoint);
string returnData = ByteArrayToString(receiveBytes);
// Uses the IPEndPoint object to determine who sent us anything
Program.form1.addlog("Received: " + returnData.ToString() + " - from " + RemoteIpEndPoint.Address.ToString() + " on port: " + RemoteIpEndPoint.Port.ToString());
// Forward this message to the website
Task.Run(() => forwardToWebsite(returnData.ToString(), RemoteIpEndPoint.Address.ToString(), RemoteIpEndPoint.Port, "udp", port));
}
Thread.Sleep(10);
}
catch (Exception e)
{
MessageBox.Show("Source : " + e.Source + "\r\n" + "Message : " + e.Message, "Error");
}
}
}
It gives me "Object reference not set to an instance of an object." on the line that says"UDPreceiver[port].Available".
Am I doing this the right way ?
Try this, it contains some bug fixes:
put your receivers in a list instead of an un-assigned array
client should be declared outside the read-loop
you are aware of the fact that this will block the calling thread?
=> use a new Thread(() => { ... }); to run the receiving part in another thread
Code below:
static class communicator
{
// Setting Variables
static List<UdpClient> UDPreceivers = new List<UdpClient>();
//static List<TcpListener> TCPreceivers = new List<TcpListener>();
static IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
static bool listening = false;
// Listener function
public static void UDPstartlistening(int port)
{
UdpClient UDPreceiver = new UdpClient(port); // udp server
UDPreceivers.Add(UDPreceiver);
// Startlistening
listening = true;
while (listening)
{
try
{
if (UDPreceiver.Available > 0) // Only read if we have some data queued in buffer
{
//IPEndPoint object will allow us to read datagrams sent from any tracker.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
// Blocks untill data is received
Byte[] receiveBytes = UDPreceiver.Receive(ref RemoteIpEndPoint);
string returnData = ByteArrayToString(receiveBytes);
// Uses the IPEndPoint object to determine who sent us anything
Program.form1.addlog("Received: " + returnData.ToString() + " - from " + RemoteIpEndPoint.Address.ToString() + " on port: " + RemoteIpEndPoint.Port.ToString());
// Forward this message to the website
Task.Run(() => forwardToWebsite(returnData.ToString(), RemoteIpEndPoint.Address.ToString(), RemoteIpEndPoint.Port, "udp", port));
}
Thread.Sleep(10);
}
catch (Exception e)
{
MessageBox.Show("Source : " + e.Source + "\r\n" + "Message : " + e.Message, "Error");
}
}
}
}
I Think you need to have a closer look at examples all over internet, the object you just created UDPreceiver[port] is not in the state for receiving data. According to here the object should call BeginReceive. Have no C# but this might help.
I have an app which pings IP or IP range. The problem is that when hosts are closed it takes longer to ping than they are open. When host is closed the time to ping is about 1-2 seconds.
How could I make it faster when hosts are closed?
This is my code:
using System;
using System.Text;
using System.Windows.Forms;
using System.Net.NetworkInformation;
namespace Range_Pinger
{
public partial class PingIPRange : Form
{
uint startIP, endIP, currentIP;
int count = 0;
int open = 0;
int closed = 0;
public PingIPRange()
{
InitializeComponent();
tmrPingInterval.Tick += new EventHandler(tmrPingInterval_Tick);
}
void tmrPingInterval_Tick(object sender, EventArgs e)
{
if (txtTo.Text == string.Empty) Ping(ip2str(startIP));
else
{
if (currentIP >= endIP) tmrPingInterval.Stop();
Ping(ip2str(currentIP));
currentIP++;
}
count++;
tsslPingCount.Text = "Total number of pings: " + count.ToString() +
" Open IPs: " + open.ToString() + " Closed IPs: " + closed.ToString();
}
static uint str2ip(string ip)
{
string[] numbers = ip.Split('.');
uint x1 = (uint)(Convert.ToByte(numbers[0]) << 24);
uint x2 = (uint)(Convert.ToByte(numbers[1]) << 16);
uint x3 = (uint)(Convert.ToByte(numbers[2]) << 8);
uint x4 = (uint)(Convert.ToByte(numbers[3]));
return x1 + x2 + x3 + x4;
}
static string ip2str(uint ip)
{
string s1 = ((ip & 0xff000000) >> 24).ToString() + ".";
string s2 = ((ip & 0x00ff0000) >> 16).ToString() + ".";
string s3 = ((ip & 0x0000ff00) >> 8).ToString() + ".";
string s4 = (ip & 0x000000ff).ToString();
return s1 + s2 + s3 + s4;
}
private void btnPing_Click(object sender, EventArgs e)
{
txtDisplay.Text = string.Empty;
tsslPingCount.Text = string.Empty;
count = 0;
open = 0;
closed = 0;
tmrPingInterval.Interval = int.Parse(nudInterval.Value.ToString());
try
{
startIP = str2ip(txtFrom.Text);
if (txtTo.Text != string.Empty) endIP = str2ip(txtTo.Text);
currentIP = startIP;
tmrPingInterval.Start();
}
catch
{
MessageBox.Show("Invalid input. It must be something like: 255.255.255.255");
}
}
private void btnStop_Click(object sender, EventArgs e)
{
tmrPingInterval.Stop();
}
private void Ping(string address)
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "01234567890123456789012345678901";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
try
{
PingReply reply = pingSender.Send(address, timeout, buffer, options) ;
if (reply.Status == IPStatus.Success)
{
open++;
txtDisplay.AppendText("Host " + address + " is open." + Environment.NewLine);
}
else
{
closed++;
txtDisplay.AppendText("Host " + address + " is closed." + Environment.NewLine);
}
}
catch (Exception ex)
{
txtDisplay.SelectedText += Environment.NewLine + ex.Message;
}
}
private void tsmiExit_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
This is what I have now:
[DllImport("iphlpapi.dll", ExactSpelling = true)]
public static extern int SendARP(IPAddress DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen);
private void Ping(IPAddress address)
{
byte[] macAddr = new byte[6];
uint macAddrLen = (uint)macAddr.Length;
if (SendARP(address, 0, macAddr, ref macAddrLen) == 0)
{
txtDisplay.AppendText("Host " + address + " is open." + Environment.NewLine);
}
else txtDisplay.AppendText("Host " + address + " is closed." + Environment.NewLine);
}
You shouldn't reduce the timeout. Try to send multiple pings at once async.
var ping = new Ping();
ping.PingCompleted += (sender, eventArgs) =>
{
// eventArgs.Reply.Address
// eventArgs.Reply.Status
};
ping.SendAsync(ip, etc.);
Your address is a string. Thus it will go via DNS first to see if this is possibly a hostname (even if it is an IP address).
I suggest you use the overload taking an IPAddress instead.
I created a live host scanner not too long ago. It uses ARP to check if a computer is online.
An ARP request is much faster than if you'd ping a host.
Here's the code I used to check if a Host is available:
//You'll need this pinvoke signature as it is not part of the .Net framework
[DllImport("iphlpapi.dll", ExactSpelling = true)]
public static extern int SendARP(int DestIP, int SrcIP,
byte[] pMacAddr, ref uint PhyAddrLen);
//These vars are needed, if the the request was a success
//the MAC address of the host is returned in macAddr
private byte[] macAddr = new byte[6];
private uint macAddrLen;
//Here you can put the IP that should be checked
private IPAddress Destination = IPAddress.Parse("127.0.0.1");
//Send Request and check if the host is there
if (SendARP((int)Destination.Address, 0, macAddr, ref macAddrLen) == 0)
{
//SUCCESS! Igor it's alive!
}
If you're interested Nmap also uses this technique to scan for available hosts.
ARP scan puts Nmap and its optimized algorithms in charge of ARP requests. And if it gets a response back, Nmap doesn't even need to worry about the IP-based ping packets since it already knows the host is up. This makes ARP scan much faster and more reliable than IP-based scans. So it is done by default when scanning ethernet hosts that Nmap detects are on a local ethernet network. Even if different ping types (such as -PE or -PS) are specified, Nmap uses ARP instead for any of the targets which are on the same LAN.
EDIT:
This only works within the current subnet! As long as there is no router between the requesting machine and the target it should work fine.
ARP is a non-routable protocol, and can therefore only be used between systems on the same Ethernet network. [...]
arp-scan can be used to discover IP hosts on the local network. It can discover all hosts, including those that block all IP traffic such as firewalls and systems with ingress filters. - Excerpt from NTA-Monitor wiki
For more information on the SendARP function you can check the pinvoke.net documentation.
You need to redesign your application to use multithreading -> tasks. Issue a task for each ping, and when you receive a response from a given host fire an event and update the UI. Changing socket timeout will only help you to reduce the timeout from outrageous to insufferable.
Not sure if this is any help (see final post on the thread), it seems an almost identical problem. What you're butting up against there is the protocol stack's timeout. You can get around it if you use socket to connect as you'll have more control.