An existing connection was forcibly closed by the remote host...

E

Erakis

Hi

My CF application have to be connected to a TCP server on a PC.
Here is the way I do on client :

Code:
private void Connect(string ip, int portNumber)

clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);

clientSocket.Connect(new IPEndPoint(ip, portNumber));
receivedThread = new Thread(new ThreadStart(ReceiveThread));

private void ReceiveThread()
{
byte[] buffer = new byte[512];
int iBytesCount = 0;
while (!stopThread)
{
try
{
iBytesCount = this.clientSocket.Receive(buffer, 0,
this.receiveBufferSize, SocketFlags.None); ;
if (iBytesCount == 0)
break;
}
catch (Exception ex)
{
if (!stopThread)
{
throw new CommunicationException("An exception occured
in received thread.", ex);
}
break;
}
...
}

The first time the PPC connect to the server all is well working :)
But If I shut down the Pocket PC using the power button on the device, and
exception occured in the ReceivedThread method. The exception is "A blocking
operation was interrupted by a call to WSACancelBlockingCall".

In this case, a Dispose the Socket and try to reconnect using the Connect
method. The Socket.Connect succed but each time this line is executed :
Code:
iBytesCount = this.clientSocket.Receive(buffer, 0, this.receiveBufferSize,
SocketFlags.None); ;

I got the following exception "An existing connection was forcibly closed by
the remote host". Why ??? I'm unable to reconnect the Pocket PC to the server
!

Two days trying to figuring the problem but I now I don't know what to do :(
Please help me.
 
M

Michael Rubinstein

Erakis, I recommend using asynchronous sockets. Instead of calling

clientSocket.Connect(new IPEndPoint(ip, portNumber));

declare a callback method and issue:

clientSocket.BeginConnect(new IPEndPoint(ip,portNumber, new
AsyncCallback(onClientConnect),clientSocket);

where the callback method could be something like:

private void onClientSocketConnect(IAsyncResult ar)
{
Socket socket = (Socket)ar.AsyncState;
//an object that would store a reference to your socket and the
buffer for data
StateObject so = new StateObject(socket);
socket.BeginReceive(so.Buffer,0,so.BufferSize,SocketFlags.None,new
AsyncCallback(onClientSocketReceive), so);
}

onClientSocketReceive() here is another callback method you have to write.
The StateObject class, instantiated in this method, could be something like:

public class StateObject
{
private byte[] buffer = new Byte[512];
private Socket clientSocket;

public StateObject(Socket socket)
{
this.clientSocket = socket;
}
public Socket ClientSocket
{
get { return clientSocket; }
}
public int BufferSize
{
get { return this.buffer.Length; }
}
public Byte[] Buffer
{
get { return this.buffer; }
}
}


VS help for Socket class describes in detail how to declare and use these
callback methods. In my experience there is no difference in maintaining
connections between mobile devices and PCs. Testing on a PC is easier. If
your code running on a PC can survive pulling a network cable out, then
putting it back, the same code running under CF should recover from broken
connections. If you decide using asynchronous sockets on the client side, it
makes sense doing likewise on the server side.

Michael



Erakis said:
Hi

My CF application have to be connected to a TCP server on a PC.
Here is the way I do on client :

Code:
private void Connect(string ip, int portNumber)

clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);

clientSocket.Connect(new IPEndPoint(ip, portNumber));
receivedThread = new Thread(new ThreadStart(ReceiveThread));

private void ReceiveThread()
{
byte[] buffer = new byte[512];
int iBytesCount = 0;
while (!stopThread)
{
try
{
iBytesCount = this.clientSocket.Receive(buffer, 0,
this.receiveBufferSize, SocketFlags.None); ;
if (iBytesCount == 0)
break;
}
catch (Exception ex)
{
if (!stopThread)
{
throw new CommunicationException("An exception occured
in received thread.", ex);
}
break;
}
...
}

The first time the PPC connect to the server all is well working :)
But If I shut down the Pocket PC using the power button on the device, and
exception occured in the ReceivedThread method. The exception is "A
blocking
operation was interrupted by a call to WSACancelBlockingCall".

In this case, a Dispose the Socket and try to reconnect using the Connect
method. The Socket.Connect succed but each time this line is executed :
Code:
iBytesCount = this.clientSocket.Receive(buffer, 0, this.receiveBufferSize,
SocketFlags.None); ;

I got the following exception "An existing connection was forcibly closed
by
the remote host". Why ??? I'm unable to reconnect the Pocket PC to the
server
!

Two days trying to figuring the problem but I now I don't know what to do
:(
Please help me.
 
E

Erakis

    Erakis, I recommend using asynchronous sockets. Instead of calling

    clientSocket.Connect(new IPEndPoint(ip, portNumber));

declare a callback method and issue:

    clientSocket.BeginConnect(new IPEndPoint(ip,portNumber, new
AsyncCallback(onClientConnect),clientSocket);

where the callback method could be something like:

    private void onClientSocketConnect(IAsyncResult ar)
    {
        Socket socket = (Socket)ar.AsyncState;
        //an object that would store a reference to your socket and the
buffer for data
        StateObject so = new StateObject(socket);
        socket.BeginReceive(so.Buffer,0,so.BufferSize,SocketFlags.None,new
AsyncCallback(onClientSocketReceive), so);
    }

onClientSocketReceive() here is another callback method you have to write.
The StateObject class, instantiated in this method, could be something like:

    public class StateObject
    {
        private byte[] buffer = new Byte[512];
        private Socket clientSocket;

        public StateObject(Socket socket)
        {
            this.clientSocket = socket;
        }
        public Socket ClientSocket
        {
            get { return clientSocket; }
        }
        public int BufferSize
        {
            get { return this.buffer.Length; }
        }
        public Byte[] Buffer
        {
            get { return this.buffer; }
        }
    }

VS help for Socket class describes in detail how to declare and use these
callback methods. In my experience there is no difference in maintaining
connections between mobile devices and PCs. Testing on a PC is easier. If
your code running on a PC can survive pulling a network cable out, then
putting it back, the same code running under CF should recover from broken
connections. If you decide using asynchronous sockets on the client side, it
makes sense doing likewise on the server side.

    Michael




My CF application have to be connected to a TCP server on a PC.
Here is the way I do on client :
Code:
private void Connect(string ip, int portNumber)[/QUOTE]
[QUOTE]
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);[/QUOTE]
[QUOTE]
clientSocket.Connect(new IPEndPoint(ip, portNumber));
receivedThread = new Thread(new ThreadStart(ReceiveThread));[/QUOTE]
[QUOTE]
private void ReceiveThread()
{
  byte[] buffer = new byte[512];
  int iBytesCount = 0;
  while (!stopThread)
  {
     try
     {
         iBytesCount = this.clientSocket.Receive(buffer, 0,
this.receiveBufferSize, SocketFlags.None); ;
         if (iBytesCount == 0)
             break;
       }
       catch (Exception ex)
       {
             if (!stopThread)
             {
                   throw new CommunicationException("An exception occured
in received thread.", ex);
             }
             break;
        }
        ...
}
The first time the PPC connect to the server all is well working :)
But If I shut down the Pocket PC using the power button on the device, and
exception occured in the ReceivedThread method. The exception is "A
blocking
operation was interrupted by a call to WSACancelBlockingCall".
In this case, a Dispose the Socket and try to reconnect using the Connect
method. The Socket.Connect succed but each time this line is executed :
Code:
iBytesCount = this.clientSocket.Receive(buffer, 0, this.receiveBufferSize,
SocketFlags.None); ;
I got the following exception "An existing connection was forcibly closed
by
the remote host". Why ??? I'm unable to reconnect the Pocket PC to the
server
!
Two days trying to figuring the problem but I now I don't know what to do
:(
Please help me.- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -

First of all, thank for your help :)

I already know how to use BeginConnect, BeginReceived, etc... but the
entire project is built
using a custom thread for read event and I don't think this is related
to our current problem :(
I mean If I use BeginReceived instead of my own thread and
Socket.Received, the exception will be
throw in EndReceived method anyway.... Or maybe I don't understand
what you are trying to explain
me ?

Else the main problem is that PocketPC "SOCKET" don't seem to be able
to reconnect properly
to the server. The connect method succed but as long as we try to read
on the socket an exception
is thrown. Like a phantom connection :( But If I close the the
application and reconnect using the same
code, same address, etc.. the connection to server and read operation
succeed without any problem...

PS : I did not think about the idea of unplug a network cable on PC.
It will be more easly to debug.
Thanks for the tips.

Regars,
 
M

Michael Rubinstein

Erakis,I mean If I use BeginReceived instead of my own thread and
Socket.Received, the exception will be
throw in EndReceived method anyway.... Or maybe I don't understand
what you are trying to explain
me ?yes, EndReceive() will throw "Can't access disposed object" exception
whenever the connection is terminated. For that reason it should be always
placed within try/catch. In MS .NET Socket implementation there is no
mechanism for the socket object to signal to the main thread that it is
about to be disposed.
using a custom thread for read event and I don't think this is related
to our current problem :(your problem is probably caused by blocked calls. Asynchronous methods are
non-blocking. When using synchronous methods you could set Socket.Blocking
to false. I can't tell if this could cure your problem or what implications
are. I am using only asynchronous sockets. I don't think there is more then
a few hours to rewrite from synchronous to asynchronous sockets. Whatever
you do in your 'custom thread' you should be able doing in a callback
method. I have asynchronous sockets code running on Windows Mobile 5 and 6.

I am not sure what the power button on your Pocket PC device does. I am
working with cell phones (PDA, SmartPhone). Those I got have a button that
when pressed shuts down the display, keyboard (if any), locks most buttons,
and reduces power consumption to a bare minimum. My applications continue to
run and receive data. The same button held down for a few seconds would shut
down the device completely, including the OS and all running applications.
PS : I did not think about the idea of unplug a network cable on PC.If your code can handle this, then you are on a right track. If you don't
test it yourself, your clients will.

Cheers, Michael

What I am trying to tell you that using asynchronous socket model is
Erakis, I recommend using asynchronous sockets. Instead of calling

clientSocket.Connect(new IPEndPoint(ip, portNumber));

declare a callback method and issue:

clientSocket.BeginConnect(new IPEndPoint(ip,portNumber, new
AsyncCallback(onClientConnect),clientSocket);

where the callback method could be something like:

private void onClientSocketConnect(IAsyncResult ar)
{
Socket socket = (Socket)ar.AsyncState;
//an object that would store a reference to your socket and the
buffer for data
StateObject so = new StateObject(socket);
socket.BeginReceive(so.Buffer,0,so.BufferSize,SocketFlags.None,new
AsyncCallback(onClientSocketReceive), so);
}

onClientSocketReceive() here is another callback method you have to write.
The StateObject class, instantiated in this method, could be something
like:

public class StateObject
{
private byte[] buffer = new Byte[512];
private Socket clientSocket;

public StateObject(Socket socket)
{
this.clientSocket = socket;
}
public Socket ClientSocket
{
get { return clientSocket; }
}
public int BufferSize
{
get { return this.buffer.Length; }
}
public Byte[] Buffer
{
get { return this.buffer; }
}
}

VS help for Socket class describes in detail how to declare and use these
callback methods. In my experience there is no difference in maintaining
connections between mobile devices and PCs. Testing on a PC is easier. If
your code running on a PC can survive pulling a network cable out, then
putting it back, the same code running under CF should recover from broken
connections. If you decide using asynchronous sockets on the client side,
it
makes sense doing likewise on the server side.

Michael




My CF application have to be connected to a TCP server on a PC.
Here is the way I do on client :
Code:
private void Connect(string ip, int portNumber)[/QUOTE]
[QUOTE]
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);[/QUOTE]
[QUOTE]
clientSocket.Connect(new IPEndPoint(ip, portNumber));
receivedThread = new Thread(new ThreadStart(ReceiveThread));[/QUOTE]
[QUOTE]
private void ReceiveThread()
{
byte[] buffer = new byte[512];
int iBytesCount = 0;
while (!stopThread)
{
try
{
iBytesCount = this.clientSocket.Receive(buffer, 0,
this.receiveBufferSize, SocketFlags.None); ;
if (iBytesCount == 0)
break;
}
catch (Exception ex)
{
if (!stopThread)
{
throw new CommunicationException("An exception occured
in received thread.", ex);
}
break;
}
...
}
The first time the PPC connect to the server all is well working :)
But If I shut down the Pocket PC using the power button on the device,
and
exception occured in the ReceivedThread method. The exception is "A
blocking
operation was interrupted by a call to WSACancelBlockingCall".
In this case, a Dispose the Socket and try to reconnect using the
Connect
method. The Socket.Connect succed but each time this line is executed :
Code:
iBytesCount = this.clientSocket.Receive(buffer, 0,
this.receiveBufferSize,
SocketFlags.None); ;
I got the following exception "An existing connection was forcibly
closed
by
the remote host". Why ??? I'm unable to reconnect the Pocket PC to the
server
!
Two days trying to figuring the problem but I now I don't know what to
do
:(
Please help me.- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -

First of all, thank for your help :)

I already know how to use BeginConnect, BeginReceived, etc... but the
entire project is built
using a custom thread for read event and I don't think this is related
to our current problem :(
I mean If I use BeginReceived instead of my own thread and
Socket.Received, the exception will be
throw in EndReceived method anyway.... Or maybe I don't understand
what you are trying to explain
me ?

Else the main problem is that PocketPC "SOCKET" don't seem to be able
to reconnect properly
to the server. The connect method succed but as long as we try to read
on the socket an exception
is thrown. Like a phantom connection :( But If I close the the
application and reconnect using the same
code, same address, etc.. the connection to server and read operation
succeed without any problem...

PS : I did not think about the idea of unplug a network cable on PC.
It will be more easly to debug.
Thanks for the tips.

Regars,
 
S

Simon Hart [MVP]

There is a bug in the socket networking stack on WinCE, and CF property
Socket.Connected is true no matter what. Do not rely on this property,
instead handle the exception.

--
Simon Hart
Visual Developer - Device Application Development MVP
http://www.simonrhart.com

in message news:[email protected]...
 

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