R
Robin
Here is the run down. It is a Client/Server application where the client
requests data from the server and the request is fufilled as a reply using
the same connection.
The "An existing connection was forcibly closed by the remote host"
exception rises on the Client under strange circumstances, since if I track
the server's output it shows that the data was send to the Client
successfully (all 217 bytes for example), but on the Client side it gets
this exception and 0 bytes are read.
Here is how the Server is started and Reads the Socket if this helps:
protected void InitializeServer(int nPort)
{
tcpLsn = new TcpListener(nPort);
tcpLsn.Start();
tcpThd = new Thread(new ThreadStart(WaitingForClient));
tcpThd.Start();
}
public void WaitingForClient()
{
ClientData CData;
while(true)
{ /* Accept will block until someone connects */
CData.structSocket = tcpLsn.AcceptSocket();
Interlocked.Increment(ref connectId);
CData.structThread = new Thread(new ThreadStart(ReadSocket));
lock(this)
{ // it is used to keep connected Sockets and active thread
dataHolder.Add(connectId, CData);
}
CData.structThread.Start();
}
}
public void ReadSocket()
{
/* realId will be not changed for each thread, but connectId is
* changed. it can't be used to delete object from Hashtable*/
long realId = connectId;
Byte[] receive;
ClientData cd = (ClientData)dataHolder[realId];
Socket s = cd.structSocket;
int ret = 0;
string sData = null;
string[] sReceived;
bool bExit = false; // Exit on Success
while (!bExit)
{
if(s.Connected)
{
receive = new Byte[100] ;
try
{
ret = s.Receive(receive,receive.Length,0);
// Do stuff with received data AND send back a response
int sentBytes =
s.Send(Encoding.UTF8.GetBytes(sData),Encoding.UTF8.GetBytes(sData).Length,SocketFlags.None);
}
catch (Exception e)
{
if( !s.Connected )
{
break;
}
else
cwp.mobile.utils.DisplayError(e);
}
bExit = true;
}
}
CloseTheThread(realId);
}
private void CloseTheThread(long realId)
{
try
{
ClientData clientData = (ClientData)dataHolder[realId];
clientData.structThread.Abort();
}
catch(Exception )
{ lock(this)
{
dataHolder.Remove(realId);
}
}
}
And here is how the client essentially works, it is a simple Single Threaded
connection. And just a foot note about the code below I use it in 2
different projects, one is a wired client running on a Win32 machine and the
other is running on a Wireless handheld running Windows Mobile, and both are
getting the exact same problem. At first I thought it was communication
(wireless network problems) but I have my doubts.
// Pass the function data as a string and TRUE boolean value to wait for the
reply (blocking)
private string SendServerData(string sData, bool bReadWait)
{
try
{
tcpclnt = new TcpClient();
tcpclnt.Connect(new IPEndPoint(IPAddress.Parse(this.config.sIpAddress),
this.config.nPort));
stm = tcpclnt.GetStream();
const int byteCount = 300;
int readBytes = 0;
writeToServer(sData);
if(bReadWait)
{
bool exit = false;
while(!exit)
{
try
{ readBuffer = new Byte[byteCount];
readBytes = stm.Read(readBuffer,0,byteCount);
if(Encoding.ASCII.GetString(readBuffer,0,readBytes).Length > 0)
exit = true;
}
catch (Exception){break;}
}
stm.Close();
tcpclnt.Close();
return Encoding.ASCII.GetString(readBuffer,0,readBytes);
}
else
return "";
}
catch(SocketException sockexcep)
{
cwp.mobile.utils.DisplayError(sockexcep);
return "-1";
}
catch(Exception e)
{
cwp.mobile.utils.DisplayError(e);
return "-1";
}
}
private void writeToServer(string sData)
{
ASCIIEncoding encord = new ASCIIEncoding();
writeBuffer = encord.GetBytes(sData);
if(stm != null)
stm.Write(writeBuffer,0,writeBuffer.Length);
}
Any thoughts at all on how to improve either of these would be awesome
because I spend 2 hours googling this and have come up with nothing
substantial.
Thanks
requests data from the server and the request is fufilled as a reply using
the same connection.
The "An existing connection was forcibly closed by the remote host"
exception rises on the Client under strange circumstances, since if I track
the server's output it shows that the data was send to the Client
successfully (all 217 bytes for example), but on the Client side it gets
this exception and 0 bytes are read.
Here is how the Server is started and Reads the Socket if this helps:
protected void InitializeServer(int nPort)
{
tcpLsn = new TcpListener(nPort);
tcpLsn.Start();
tcpThd = new Thread(new ThreadStart(WaitingForClient));
tcpThd.Start();
}
public void WaitingForClient()
{
ClientData CData;
while(true)
{ /* Accept will block until someone connects */
CData.structSocket = tcpLsn.AcceptSocket();
Interlocked.Increment(ref connectId);
CData.structThread = new Thread(new ThreadStart(ReadSocket));
lock(this)
{ // it is used to keep connected Sockets and active thread
dataHolder.Add(connectId, CData);
}
CData.structThread.Start();
}
}
public void ReadSocket()
{
/* realId will be not changed for each thread, but connectId is
* changed. it can't be used to delete object from Hashtable*/
long realId = connectId;
Byte[] receive;
ClientData cd = (ClientData)dataHolder[realId];
Socket s = cd.structSocket;
int ret = 0;
string sData = null;
string[] sReceived;
bool bExit = false; // Exit on Success
while (!bExit)
{
if(s.Connected)
{
receive = new Byte[100] ;
try
{
ret = s.Receive(receive,receive.Length,0);
// Do stuff with received data AND send back a response
int sentBytes =
s.Send(Encoding.UTF8.GetBytes(sData),Encoding.UTF8.GetBytes(sData).Length,SocketFlags.None);
}
catch (Exception e)
{
if( !s.Connected )
{
break;
}
else
cwp.mobile.utils.DisplayError(e);
}
bExit = true;
}
}
CloseTheThread(realId);
}
private void CloseTheThread(long realId)
{
try
{
ClientData clientData = (ClientData)dataHolder[realId];
clientData.structThread.Abort();
}
catch(Exception )
{ lock(this)
{
dataHolder.Remove(realId);
}
}
}
And here is how the client essentially works, it is a simple Single Threaded
connection. And just a foot note about the code below I use it in 2
different projects, one is a wired client running on a Win32 machine and the
other is running on a Wireless handheld running Windows Mobile, and both are
getting the exact same problem. At first I thought it was communication
(wireless network problems) but I have my doubts.
// Pass the function data as a string and TRUE boolean value to wait for the
reply (blocking)
private string SendServerData(string sData, bool bReadWait)
{
try
{
tcpclnt = new TcpClient();
tcpclnt.Connect(new IPEndPoint(IPAddress.Parse(this.config.sIpAddress),
this.config.nPort));
stm = tcpclnt.GetStream();
const int byteCount = 300;
int readBytes = 0;
writeToServer(sData);
if(bReadWait)
{
bool exit = false;
while(!exit)
{
try
{ readBuffer = new Byte[byteCount];
readBytes = stm.Read(readBuffer,0,byteCount);
if(Encoding.ASCII.GetString(readBuffer,0,readBytes).Length > 0)
exit = true;
}
catch (Exception){break;}
}
stm.Close();
tcpclnt.Close();
return Encoding.ASCII.GetString(readBuffer,0,readBytes);
}
else
return "";
}
catch(SocketException sockexcep)
{
cwp.mobile.utils.DisplayError(sockexcep);
return "-1";
}
catch(Exception e)
{
cwp.mobile.utils.DisplayError(e);
return "-1";
}
}
private void writeToServer(string sData)
{
ASCIIEncoding encord = new ASCIIEncoding();
writeBuffer = encord.GetBytes(sData);
if(stm != null)
stm.Write(writeBuffer,0,writeBuffer.Length);
}
Any thoughts at all on how to improve either of these would be awesome
because I spend 2 hours googling this and have come up with nothing
substantial.
Thanks