C# socket reconnect

C

Cheryl

Hi. I am having a problem on handling asynchronous sockets in C#. I
implemented a pair of client and server sockets. The connection is ok when
first connected. However, when I turned off the server socket, the client
is able to connect, but cannot send anything out. It seems that the
Socket.Connected is false but I received no disconnection event. Any idea
on how to solve the problem?

Thanks.


using System;
using System.Collections.Generic;
using System.Text;

using System.Net.Sockets;
using System.Threading;

using System.Collections;

namespace socket
{
public sealed class SocketClient
{

Queue qsend = null;
//default setting
private const int DEFAULT_PORT = 1024;
private const string DEFAULT_IP = "127.0.0.1";
private const int SOCKET_BUFFER_SIZE = 256;

public delegate void ErrorEvent(object sender, string err);
public event ErrorEvent OnErrorEvent;

public delegate void ConnectEvent(object sender);
public event ConnectEvent OnConnectEvent;

public delegate void DisconnectEvent(object sender);
public event DisconnectEvent OnDisconnectEvent;

public delegate void ReceiveEvent(object sender, byte[] buffer, int
len);
public event ReceiveEvent OnReceiveEvent;

private static ManualResetEvent sendDone = new
ManualResetEvent(false);

private Socket handle = null;

private int bytesSent = 0;

private string ip;

private int port;

public bool Connected
{
get
{
return Handle.Connected;
}
}

//socket handle
public Socket Handle
{
get
{
return handle;
}
set
{
handle = value;
}
}


/// <summary>
/// Constructor
/// </summary>
public SocketClient()
{

try
{
qsend = new Queue();

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

ip = DEFAULT_IP;
port = DEFAULT_PORT;
}
catch (SocketException e)
{
ThrowError(e.Message);
}
}


public SocketClient(Socket workerSocket)
{
try
{
qsend = new Queue();

handle = workerSocket;

ip = DEFAULT_IP;
port = DEFAULT_PORT;
}
catch (SocketException e)
{
ThrowError(e.Message);
}
}


public void Connect(string ip, int port)
{
this.ip = ip;
this.port = port;
try
{
//Console.WriteLine(this, "Begin Connect");
handle.BeginConnect(ip, port, new
AsyncCallback(OnConnectCallBack), null);
}
catch (SocketException e)
{
ThrowError(e.Message);
}
catch (Exception e)
{
ThrowError(e.Message);
}
}


private void OnConnectCallBack(IAsyncResult asyn)
{
try
{
//Console.WriteLine(this, "End Connect");
handle.EndConnect(asyn);

if (OnConnectEvent != null)
{
OnConnectEvent(this);
}
else
{
Console.WriteLine(this, "OnConnectEvent = null");
}
}
catch (SocketException e)
{
ThrowError(e.Message);
}
catch (Exception e)
{
ThrowError(e.Message);
}
}


public void Disconnect()
{
try
{
handle.BeginDisconnect(true, new
AsyncCallback(OnDisconnectCallBack), null);
}
catch (SocketException e)
{
ThrowError(e.Message);
}
catch (Exception e)
{
ThrowError(e.Message);
}
}


private void CloseSocket()
{
try
{
Console.WriteLine(this, "CloseSocket");
handle.Shutdown(SocketShutdown.Both);
handle.Close();

//if (OnDisconnectEvent != null)
//{
// OnDisconnectEvent(this);
//}
}
catch (SocketException e)
{
ThrowError(e.Message);
//throw e;
}
catch (Exception e)
{
ThrowError(e.Message);
//throw e;
}
finally
{
if (OnDisconnectEvent != null)
{
OnDisconnectEvent(this);
}
}
}


private void OnDisconnectCallBack(IAsyncResult asyn)
{
try
{
handle.EndDisconnect(asyn);

CloseSocket();
}
catch (SocketException e)
{
ThrowError(e.Message);
}
catch (Exception e)
{
ThrowError(e.Message);
}
}

public void Send(byte[] buffer, int len)
{
lock (qsend)
{


try
{
//int bytesSent = 0;
bytesSent = 0;
int bytesRemain = len - bytesSent;

while (bytesSent < buffer.Length)
{
bytesRemain = len - bytesSent;

byte[] sendBuffer = new byte[bytesRemain];

Array.Copy(buffer, bytesSent, sendBuffer, 0,
bytesRemain);

try
{
bytesSent += AsyncSend(sendBuffer, bytesRemain);

if (bytesSent != len)
{
int j = 0;
}
}
catch (SocketException e)
{
ThrowError(e.Message);
//throw e;
}
catch (Exception e)
{
ThrowError(e.Message);
//throw e;
}
}
}
catch (Exception e)
{
ThrowError(e.Message);
//throw e;
}
}
}

private void OnSendCallBack1(IAsyncResult asyn)
{

//int bytesSent = (int)asyn.AsyncState;

SocketError err = new SocketError();

bytesSent = handle.EndSend(asyn, out err);
}


public int AsyncSend(byte[] buffer, int len)
{
try
{
sendDone.Reset();

bytesSent = 0;

handle.BeginSend(
buffer,
0,
len,
SocketFlags.None,
new AsyncCallback(OnSendCallBack),
null);

sendDone.WaitOne();

return bytesSent;
}
catch (SocketException e)
{
ThrowError(e.Message);
return -1;
throw e;
}
catch (Exception e)
{
ThrowError(e.Message);
return -1;
throw e;
}
}


private void OnSendCallBack(IAsyncResult asyn)
{
try
{
//int bytesSent = (int)asyn.AsyncState;

SocketError err = new SocketError();

bytesSent = handle.EndSend(asyn, out err);


}
catch (SocketException e)
{
ThrowError(e.Message);
//throw e;
}
catch (Exception e)
{
ThrowError(e.Message);
//throw e;
}
finally
{
sendDone.Set();
}
}


public void Receive()
{
try
{
if (Connected)
{
byte[] buffer = new byte[SOCKET_BUFFER_SIZE];
handle.BeginReceive(buffer, 0, SOCKET_BUFFER_SIZE,
SocketFlags.None, new AsyncCallback(OnReceiveCallBack), buffer);
}
}
catch (SocketException e)
{
//error code for disconnect socket
if (e.ErrorCode == 10054)
{
CloseSocket();
}
else
{
ThrowError(e.Message);
throw e;
}
}
catch (Exception e)
{
ThrowError(e.Message);
//throw e;
}
}


private void OnReceiveCallBack(IAsyncResult asyn)
{
try
{
SocketError err = new SocketError();

int bytesRead = handle.EndReceive(asyn, out err);

if (err.ToString() != "Success")
{
Console.WriteLine(this, "OnReceiveCallBack:" +
err.ToString());
}

if (bytesRead <= 0)
{
Console.WriteLine(this, "bytesRead = 0");
CloseSocket();
}
else if (bytesRead > 0)
{
//Console.WriteLine(this, "bytesRead =" + bytesRead);
byte[] buffer = new byte[bytesRead];

Array.Copy((byte[])asyn.AsyncState, 0, buffer, 0,
bytesRead);

if (OnReceiveEvent != null)
{
OnReceiveEvent(this, buffer, bytesRead);
}

Receive();
}
}
catch (SocketException e)
{
//error code for disconnect socket
if (e.ErrorCode == 10054)
{
CloseSocket();
}
else
{
ThrowError(e.Message);
throw e;
}
}
catch (Exception e)
{
ThrowError(e.Message);
//throw e;
}
}


private void ThrowError(string err)
{
Console.WriteLine(this, err);
if (OnErrorEvent != null)
{
OnErrorEvent(this, err);
}
}


public void BeginReceiveCallback()
{
Receive();
}
}
}
 
P

Peter Duniho

Hi. I am having a problem on handling asynchronous sockets in C#. I
implemented a pair of client and server sockets. The connection is ok
when first connected. However, when I turned off the server socket, the
client is able to connect, but cannot send anything out. It seems that
the Socket.Connected is false but I received no disconnection event.
Any idea on how to solve the problem?

Can you clarify your question? What do you mean by "turned off the server
socket"? Did you actually close the socket? If so, I don't understand
why the "client is able to connect". I would expect some error to be
thrown in the call to EndConnect() (like WSAEHOSTUNREACH). You don't seem
to have any code that does anything other than display the error in this
case, so it seems possible to me that you do in fact display the error but
then haven't done any cleanup to remove the client socket that failed to
connect.

Also, a quick glance through your code shows that you are not copying the
event handler instances before executing them. This leads to the
possibility that between the time when you check for null and the time you
actually try to execute the handlers, it could become null and cause a
null reference exception.

Pete
 
C

Cheryl

thx. What I meant was to turn off the server socket and turned that on
again. Do you mean that I have to once again copy the socket.connect status
in the constructor?
 

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