TECHNOLOGIES
FORUMS
JOBS
BOOKS
EVENTS
INTERVIEWS
Live
MORE
LEARN
Training
CAREER
MEMBERS
VIDEOS
NEWS
BLOGS
Sign Up
Login
No unread comment.
View All Comments
No unread message.
View All Messages
No unread notification.
View All Notifications
Answers
Post
An Article
A Blog
A News
A Video
An EBook
An Interview Question
Ask Question
Forums
Monthly Leaders
Forum guidelines
JIO RU
NA
23
0
Socket idle timer problem in windows service
Nov 5 2012 5:14 AM
/*
Hello,
I wrote class for management clients socket connection using Windows Service.
In this class I want to manage client idle time. For this I'm using SocketPaketWithTimer,
with System.Timers.Timer and OnTimerElapsed event. The problem is, that after OnTimerElapsed
event occurred I want pass parameters in CloseClientSocket, but at this moment windows service stops responding
(When client sends "Close" the socket service closes client socket without problem).
This occurs on second client close. I think the problem is Timer event, which is executed in separate thread.
Here is my class:
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Collections;
using TheCodeKing.Net.Messaging;
using System.Globalization;
using System.Diagnostics;
using System.Threading;
using System.ComponentModel;
namespace www.gpos.ge_ws
{
class clsSocketTest
{
private int intGlobalClientCount = 0;
private string strGlobalConnIdent = "";
public AsyncCallback pfnWorkerCallBack;
/// <summary>
/// An ArrayList is used to keep track of worker sockets that are designed
/// to communicate with each connected client. Make it a synchronized ArrayList For thread safety
/// </summary>
private static System.Collections.ArrayList arrayWorkerSocketList =
ArrayList.Synchronized(new System.Collections.ArrayList());
private Socket mainSocket;
public class SocketPacket
{
public Socket m_currentSocket;
public int m_clientNumber;
public string m_clientIdent;
public DateTime m_openDateTime;
// Buffer to store the data sent by the client
public byte[] dataBuffer = new byte[1024];
// Constructor which takes a Socket and a client number
public SocketPacket(System.Net.Sockets.Socket socket, int clientNumber, string clientIdent, DateTime connOpenDateTime)
{
m_currentSocket = socket;
m_clientNumber = clientNumber;
m_clientIdent = clientIdent;
m_openDateTime = connOpenDateTime;
}
}
public class SocketPaketWithTimer
{
public SocketPacket m_currentSocketPacket;
public System.Timers.Timer m_connIdleTimer;
public SocketPaketWithTimer(SocketPacket objSocketPacket, System.Timers.Timer objSocketPacketTimer)
{
m_currentSocketPacket = objSocketPacket;
if (objSocketPacketTimer == null)
{
m_connIdleTimer = new System.Timers.Timer(20000);
m_connIdleTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerElapsed);
m_connIdleTimer.AutoReset = false;
m_connIdleTimer.Enabled = true;
m_connIdleTimer.Start();
}
else
{
m_connIdleTimer = objSocketPacketTimer;
}
}
private void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
CloseClientSocket(m_currentSocketPacket, m_connIdleTimer);
}
catch (Exception exc)
{
}
}
}
/// <summary>
/// ???????????? Socket ??????
/// </summary>
public clsSocketTest(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
{
mainSocket = new Socket(addressFamily, socketType, protocolType);
}
/// <summary>
/// TCP Server ?????? ????????
/// </summary>
public void Start(IPAddress ipAddress, int intPort)
{
try
{
IPEndPoint ipLocal = new IPEndPoint(ipAddress, intPort);
// ????? ??????? ??????? IP ?????????
mainSocket.Bind(ipLocal);
// ????? ?????
mainSocket.Listen(4);
// ??????? call back ???????? ?????????????
mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
catch (Exception exc)
{
clsSystemEvents.writeEvent("??????? ??????? ??????? ????: " + exc.Message, EventLogEntryType.Error, 1);
}
}
/// <summary>
/// ??????? TCP Server ?? ?????? ????? ????????? ???????
/// </summary>
public void Stop()
{
try
{
Socket workerSocket = null;
for (int i = 0; i < arrayWorkerSocketList.Count; i++)
{
workerSocket = (Socket)arrayWorkerSocketList[i];
if (workerSocket != null)
{
workerSocket.Close();
workerSocket = null;
}
}
if (mainSocket != null)
{
mainSocket.Close();
}
}
catch (Exception exc)
{
clsSystemEvents.writeEvent("??????? ??????? ????????? ????: " + exc.Message, EventLogEntryType.Error, 1);
}
}
/// <summary>
/// ??????? ?????????
/// </summary>
private void OnClientConnect(IAsyncResult asyn)
{
DateTime dtCurrentDateTime = System.DateTime.Now;
try
{
// Here we complete/end the BeginAccept() asynchronous call
// by calling EndAccept() - which returns the reference to
// a new Socket object
Socket workerSocket = mainSocket.EndAccept(asyn);
// Now increment the client count for this client
// in a thread safe manner
Interlocked.Increment(ref intGlobalClientCount);
strGlobalConnIdent = clsAddings.RandomString();
SocketPacket socketPacket = new SocketPacket(workerSocket, intGlobalClientCount, strGlobalConnIdent, dtCurrentDateTime);
SocketPaketWithTimer socketPaketWithTimer = new SocketPaketWithTimer(socketPacket, null);
// Add the workerSocket reference to arrayWorkerSocketList ArrayList
arrayWorkerSocketList.Add(socketPaketWithTimer);
/*
// Send a welcome message to client
string msg = "Welcome client " + m_clientCount + "\n";
SendMsgToClient(msg, m_clientCount);
// Update the list box showing the list of clients (thread safe call)
UpdateClientListControl();
*/
// Let the worker Socket do the further processing for the
// just connected client
WaitForData(socketPaketWithTimer);
// Since the main Socket is now free, it can go back and wait for
// other clients who are attempting to connect
mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
catch (Exception exc)
{
clsSystemEvents.writeEvent("??????? ???????????? ?????????? ????: " + exc.Message, EventLogEntryType.Error, 1);
}
}
/// <summary>
/// ??????? ?????????? ?????????? ??????????????
/// </summary>
private void WaitForData(SocketPaketWithTimer socPacketWithTimer)
{
try
{
if (pfnWorkerCallBack == null)
{
// Specify the call back function which is to be
// invoked when there is any write activity by the
// connected client
pfnWorkerCallBack = new AsyncCallback(OnDataReceived);
}
SocketPacket theSocPkt = socPacketWithTimer.m_currentSocketPacket;
theSocPkt.m_currentSocket.BeginReceive(theSocPkt.dataBuffer, 0,
theSocPkt.dataBuffer.Length,
SocketFlags.None,
pfnWorkerCallBack,
socPacketWithTimer);
}
catch (ObjectDisposedException exc)
{
System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
}
}
/// <summary>
/// ??????????? ??????????? ???????
/// </summary>
/// <param name="asyn"></param>
private void OnDataReceived(IAsyncResult asyn)
{
SocketPaketWithTimer socketData = (SocketPaketWithTimer)asyn.AsyncState;
DateTime dtCurrentDateTime = System.DateTime.Now;
try
{
// ??????? ??????? ???????
socketData.m_connIdleTimer.Stop();
// Complete the BeginReceive() asynchronous call by EndReceive() method
// which will return the number of characters written to the stream
// by the client
int iRx = socketData.m_currentSocketPacket.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
// Extract the characters as a buffer
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(socketData.m_currentSocketPacket.dataBuffer,
0, iRx, chars, 0);
System.String szData = new System.String(chars);
// ???????? ???????
if (szData == "Close\0")
{
CloseClientSocket(socketData.m_currentSocketPacket, socketData.m_connIdleTimer);
return;
}
// Continue the waiting for data on the Socket
WaitForData(socketData);
socketData.m_connIdleTimer.Start();
}
catch (ObjectDisposedException exc)
{
System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
}
catch (SocketException se)
{
if (se.ErrorCode == 10054) // Error code for Connection reset by peer
{
string msg = "Client " + socketData.m_currentSocketPacket.m_clientNumber + " Disconnected" + "\n";
// Remove the reference to the worker socket of the closed client
// so that this object will get garbage collected
arrayWorkerSocketList[socketData.m_currentSocketPacket.m_clientNumber - 1] = null;
//UpdateClientListControl();
}
else
{
//MessageBox.Show(se.Message);
}
}
}
/// <summary>
/// Close worker socket
/// </summary>
private static void CloseClientSocket(SocketPacket objSocketPaketToClose, System.Timers.Timer objSocketTimerToClose)
{
try
{
if (objSocketTimerToClose != null)
{
objSocketTimerToClose.Stop();
objSocketTimerToClose.Dispose();
objSocketTimerToClose = null;
}
if (objSocketPaketToClose.m_currentSocket != null)
{
objSocketPaketToClose.m_currentSocket.Shutdown(SocketShutdown.Both);
objSocketPaketToClose.m_currentSocket.Disconnect(false);
objSocketPaketToClose.m_currentSocket.Close();
objSocketPaketToClose.m_currentSocket = null;
arrayWorkerSocketList[objSocketPaketToClose.m_clientNumber - 1] = null;
}
}
catch (Exception exc)
{
clsSystemEvents.writeEvent("??????? ???????????? ???????? ????: " + exc.Message, EventLogEntryType.Error, 1);
}
}
}
}
Reply
Answers (
0
)
How to Connect http server and get new files from it using c#?
Why we create static constructor in C#