소켓 이벤트 핸들러를 등록하면 수신 이벤트 발생시 콜백으로 호출해준다.
TCP/UDP-서버/클라이언트 구분없이 모두 사용할 수 있다.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Threading;
namespace MySocketLib
{
public delegate void SocketReadHandlerCallback(Object data);
public class SocketHandler
{
public Socket sock;
public SocketReadHandlerCallback handler;
public object data;
}
public class SocketTaskScheduler
{
protected Dictionary<Socket, SocketHandler> sockHandlerTable = new Dictionary<Socket, SocketHandler>();
protected bool isRunning = false;
protected Thread thread;
protected int TIMEOUT = 1000000;
public SocketTaskScheduler()
{
}
public void RegisterSocketHandler(Socket sock, SocketReadHandlerCallback handler, object data)
{
lock (sockHandlerTable)
{
if (sock != null)
{
SocketHandler sockHandler = new SocketHandler();
sockHandler.sock = sock;
sockHandler.handler = handler;
sockHandler.data = data;
sockHandlerTable.Add(sockHandler.sock, sockHandler);
}
}
}
public void UnregisterSocketHandler(Socket sock)
{
lock (sockHandlerTable)
{
if (sock != null && sockHandlerTable.ContainsKey(sock))
{
sockHandlerTable.Remove(sock);
}
}
}
protected void SingleStep()
{
lock (sockHandlerTable)
{
try
{
ArrayList selectList = new ArrayList();
foreach (var handler in sockHandlerTable)
{
selectList.Add(handler.Key);
}
if (selectList.Count == 0)
{
Thread.Sleep(10);
return;
}
Socket.Select(selectList, null, null, TIMEOUT);
foreach (Socket sock in selectList)
{
var handler = sockHandlerTable[sock];
if (handler != null && handler.handler != null) handler.handler(handler.data);
}
}
catch (Exception ex)
{
Trace.WriteLine(ex.ToString());
}
}
}
protected void DoEventLoop()
{
while (isRunning == true)
{
SingleStep();
}
}
public void StartEventLoop()
{
if (isRunning == true) return;
thread = new Thread(new ThreadStart(DoEventLoop));
thread.IsBackground = true;
isRunning = true;
thread.Start();
}
public void StopEventLoop()
{
isRunning = false;
if (thread != null)
{
if (Thread.CurrentThread != thread)
{
thread.Join();
thread = null;
}
}
sockHandlerTable.Clear();
}
}
}
< 사용법 >
Socket clientSock;
SocketTaskScheduler task = new SocketTaskScheduler();
...
clientSock.Blocking = false;
clientSock.Connect(serverIP, serverPort);
task.RegisterSocketHandler(clientSock, IncomingPacketHandler, this);
task.StartEventLoop();
...
private void IncomingPacketHandler(object data)
{
int ret = clientSock.Receive(recvBuffer, 0, recvBuffer.Length, SocketFlags.None);
if (ret <= 0)
{
task.UnregisterSocketHandler(clientSock);
CloseSocket();
task.StopEventLoop();
}
else
{
// process recvBuffer
}
}
댓글 없음:
댓글 쓰기