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();
}
}
}
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();
}
}
}