Я пытаюсь написать асинхронный сокет в C#. Я прочитал много статей msdn и нашел эти два примера: server, client.Как определить конец потока на сервере асинхронного сокета
Я понял пример кода и использовал его для реализации своего собственного асинхронного сокета. В этом примере сервер проверяет <EOF>
, чтобы определить конец потока и отправить ответ. Я хотел бы знать, не проверяя специальный литерал, когда поток заканчивается. Моя идея состояла в том, чтобы проверить (bytesRead > 0)
и вызывать handler.BeginReceive()
рекурсивно. Смотрите следующее:
Оригинал
if (bytesRead > 0) {
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1) {
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
// Echo the data back to the client.
Send(handler, content);
} else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
Моя идея
if (received > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, received));
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
else
Send(handler, state.sb.ToString());
Если я заменить оригинальную часть с моей стороны программа прекращает работу. Я предполагаю, что клиент выполнил EndSend()
в SendCallback()
и заблокировал Thread после receiveDone.WaitOne()
в StartClient()
. Как я могу это передать? Нужно ли использовать токен, который определяет конец потока?
Есть ли еще хорошие примеры кода? Я только что нашел этих двоих.
(Evidence сервер должны получить онлайн-клиентов и поместить их в циркулирующий буфер из этого буфера, он должен читать и обрабатывать записи с multithreads.).
Редактировать
Если я использую феллинг:
if (receive > 0)
state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, receive));
if (receive == StateObject.BufferSize)
state.listener.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
else
Send(state.listener, state.sb.ToString());
Everyting работает отлично, я думаю. Это нормально? Или пропустить что-то?
Если я совмещаю два ifs, он не работает снова. Зачем?
if(receive > 0 || receive == StateObject.BufferSize)
->if(receive > 0) // Not working.
Использование токена - общий способ? Я хотел бы сначала отправить длину контента, возможно ли это? Если полученный равен размеру буфера, я могу предположить, что есть больше данных? – hofmeister
Обычно используется какой-либо разделитель, но отправка длины (или, чаще всего, числа октетов) перед отправкой данных также происходит часто. Пока у вас есть протокол, который оба оконечных устройства могут договориться о том, что вам хорошо идти. –
Хорошо, спасибо. См. Мой ** Редактировать **. Fine? – hofmeister