Я пытаюсь написать службу, которая прослушивает сокет TCP на заданном порту, пока не будет получен конец строки, а затем на основе полученной "строки" выполнит команду.
Я следовал базовому руководству по программированию сокетов для c # и придумал следующий код для прослушивания сокетов:
public void StartListening()
{
_log.Debug("Creating Maing TCP Listen Socket");
_mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, _port);
_log.Debug("Binding to local IP Address");
_mainSocket.Bind(ipLocal);
_log.DebugFormat("Listening to port {0}",_port);
_mainSocket.Listen(10);
_log.Debug("Creating Asynchronous callback for client connections");
_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
public void OnClientConnect(IAsyncResult asyn)
{
try
{
_log.Debug("OnClientConnect Creating worker socket");
Socket workerSocket = _mainSocket.EndAccept(asyn);
_log.Debug("Adding worker socket to list");
_workerSockets.Add(workerSocket);
_log.Debug("Waiting For Data");
WaitForData(workerSocket);
_log.DebugFormat("Clients Connected [{0}]", _workerSockets.Count);
_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
}
catch (ObjectDisposedException)
{
_log.Error("OnClientConnection: Socket has been closed\n");
}
catch (SocketException se)
{
_log.Error("Socket Exception", se);
}
}
public class SocketPacket
{
private System.Net.Sockets.Socket _currentSocket;
public System.Net.Sockets.Socket CurrentSocket
{
get { return _currentSocket; }
set { _currentSocket = value; }
}
private byte[] _dataBuffer = new byte[1];
public byte[] DataBuffer
{
get { return _dataBuffer; }
set { _dataBuffer = value; }
}
}
private void WaitForData(Socket workerSocket)
{
_log.Debug("Entering WaitForData");
try
{
lock (this)
{
if (_workerCallback == null)
{
_log.Debug("Initializing worker callback to OnDataRecieved");
_workerCallback = new AsyncCallback(OnDataRecieved);
}
}
SocketPacket socketPacket = new SocketPacket();
socketPacket.CurrentSocket = workerSocket;
workerSocket.BeginReceive(socketPacket.DataBuffer, 0, socketPacket.DataBuffer.Length, SocketFlags.None, _workerCallback, socketPacket);
}
catch (SocketException se)
{
_log.Error("Socket Exception", se);
}
}
public void OnDataRecieved(IAsyncResult asyn)
{
SocketPacket socketData = (SocketPacket)asyn.AsyncState;
try
{
int iRx = socketData.CurrentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
_log.DebugFormat("Created Char array to hold incomming data. [{0}]",iRx+1);
System.Text.Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
int charLength = decoder.GetChars(socketData.DataBuffer, 0, iRx, chars, 0);
_log.DebugFormat("Read [{0}] characters",charLength);
String data = new String(chars);
_log.DebugFormat("Read in String \"{0}\"",data);
WaitForData(socketData.CurrentSocket);
}
catch (ObjectDisposedException)
{
_log.Error("OnDataReceived: Socket has been closed. Removing Socket");
_workerSockets.Remove(socketData.CurrentSocket);
}
catch (SocketException se)
{
_log.Error("SocketException:",se);
_workerSockets.Remove(socketData.CurrentSocket);
}
}
Я подумал, что это послужит хорошей основой для того, что я хочу сделать, но код, который я добавил поочередно входящим символам в текстовое поле, ничего не сделал с ним. Что на самом деле не работает для того, что я хочу сделать.
Моя главная проблема - это разделение метода OnDataReceived от метода Ожидание данных. это означает, что у меня возникают проблемы при построении строки (я бы использовал построитель строк, но я могу принять несколько соединений, так что это на самом деле не работает.
В идеале я хотел бы смотреть во время прослушивания сокета, пока не увижу символ конца строки, а затем вызвать метод с результирующей строкой в качестве параметра.
Какой лучший способ сделать это.