У меня есть простой TCP-сервер, который использует асинхронные сокеты. Проблема, с которой я сталкиваюсь, такова:
У меня есть следующий класс TCP-сервера:
public class tcp_server {
const int max_clients = 300;
const int max_buffer_size = 10;
public AsyncCallback pfnWorkerCallBack;
private Socket m_mainSocket;
private Socket[] m_workerSocket = new Socket[max_clients];
private int m_clientCount = 0;
...
public void OnClientConnect(IAsyncResult asyn) { }
public void WaitForData(System.Net.Sockets.Socket soc, int socket_id) { }
public void OnDataReceived(IAsyncResult asyn)
public class SocketPacket
{
public System.Net.Sockets.Socket m_currentSocket;
public byte[] dataBuffer = new byte[max_buffer_size];
public int socket_id = -1;
}
}
Вот полный код функции OnDataRectained:
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket socketData = (SocketPacket)asyn.AsyncState; // cast
int iRx = 0;
iRx = socketData.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
WaitForData(socketData.m_currentSocket, socketData.socket_id);
}
catch (ObjectDisposedException)
{
log("OnDataReceived: Socket has been closed\n");
}
catch (SocketException se)
{
log(se.Message);
}
}
max_buffer_size установлен на 10. Если я отправлю 100 байт на сервер, onDataRecieve будет выполнен 10 раз.
У меня 3 проблемы:
1 Мне нужно «собрать» все 100 байтов и затем передать их другой функции, которая будет проверять команды в полученных данных. Клиент добавляет 4-байтовый «идентификатор конца пакета» в конец пакета, потому что размер данных не всегда известен заранее. Как / где я могу определить этот временный буфер, чтобы onDataRecieve заполнил его, если найден конец, передаст данные в функцию идентификации команды?
2 Клиент может отправить мне много данных из разных потоков (по одному соединению). Мне нужен способ иметь несколько временных буферов для каждого полученного пакета, поэтому я могу подождать, пока они не заполнятся и не передадут буфер в зависимости от того, что будет заполнено в первую очередь для функции идентификации команды, а затем для очистки / удаления буфера.
Например:
- Клиент (Thread / Packet # 1) -> Сервер (неполные данные, поток по какой-то причине зависает)
- Клиент (Thread / Packet # 2) -> Сервер (полные данные, буфер передается функции id команды)
- Клиент (Thread / Packet # 1) -> Сервер (остальные данные для 1-го пакета поступают, буфер передается команде id func)
3 Мне нужно иметь доступ к этому буферу извне (публично), чтобы я мог начать использовать этот буфер из другого класса, пока он заполняется.
Надеюсь, это имеет смысл. Как мне это сделать?