Книга: Программирование мобильных устройств на платформе .NET Compact Framework
Листинг 15.5. Класс IrDAFileReceive
Листинг 15.5. Класс IrDAFileReceive
//-------------------------------------------------------------------
//Обеспечивает прием файла через IrDA (инфракрасный порт).
//
//Этот класс НЕ является реентерабельным и не должен вызываться более
//чем одной функцией за один раз. Если необходимо иметь несколько
//сеансов связи через IR, это необходимо делать путем создания
//нескольких различных экземпляров данного класса.
//-------------------------------------------------------------------
public class IrDAFileReceive {
private bool m_wasListenerStopped;
private string m_IrDAServiceName;
private string m_fileNameForDownload;
private string m_errorDuringTransfer;
private System.Net.Sockets.IrDAListener m_irListener;
private ReceiveStatus m_ReceiveStatus;
public string ErrorText {
get {
return m_errorDuringTransfer;
}
}
//--------------------------
//Различные состояния приема
//--------------------------
public enum ReceiveStatus {
NotDone_SettingUp,
NotDone_WaitingForSender,
NotDone_Receiving,
Done_Success,
Done_Aborted,
Done_ErrorOccured
}
//------------------------------
// Возвращает состояние передачи
//------------------------------
public ReceiveStatus Status {
get {
//Обеспечить многопоточную безопасность для предотвращения
//параллельного выполнения операций чтения/записи
lock(this) {
return m_ReceiveStatus;
} //конец lock
} //конец get
} //конец свойства
private void setStatus(ReceiveStatus newStatus) {
//Обеспечить многопоточную безопасность для предотвращения
//параллельного выполнения операций чтения/записи
lock(this) {
m_ReceiveStatus = newStatus;
} //конец lock
}
//--------------------------------------------------
// [in] filename: желаемое имя для входного файла IR
//--------------------------------------------------
public IrDAFileReceive(string filename, string irdaServiceName) {
//Имя сокета IrDA, который мы хотим открыть
m_IrDAServiceName = irdaServiceName;
//Имя файла, в котором мы хотим сохранить полученные данные
m_fileNameForDownload = filename;
}
//----------------------------------------------------------
//Обеспечивает асинхронный прием файла через IR
//
// [in] filename: имя файла, в который осуществляется запись
//----------------------------------------------------------
public void WaitForIRFileDownloadAsync() {
//Заметьте, что сейчас мы находимся в режиме подготовки
setStatus(ReceiveStatus.NotDone_SettingUp);
//-------------------
//Создать новый поток
//-------------------
System.Threading.ThreadStart threadEntryPoint;
threadEntryPoint =
new System.Threading.ThreadStart(WaitForIRFileDownload);
System.Threading.Thread newThread = new System.Threading.Thread(threadEntryPoint);
//Запустить поток на выполнение
newThread.Start();
}
//------------------------------------------
//Открывает порт IR и ожидает загрузки файла
//------------------------------------------
public void WaitForIRFileDownload() {
System.IO.Stream outputStream = null;
System.Net.Sockets.IrDAClient irdaClient = null;
System.IO.Stream irStreamIn = null;
try {
//=========================================================
//Задать и загрузить файл!
//=========================================================
internal WaitForIRFileDownload(ref outputStream,ref irdaClient, ref irStreamIn);
} catch
//Поглотить любые возникающие ошибки
{
setStatus(ReceiveStatus.Done_ErrorOccured);
}
//=============================================
//Освободить все ресурсы
//=============================================
//Закрыть наш входной поток
if (irStreamIn != null) {
try {
irStreamIn.Close();
} catch {} //Поглотить любые возникающие ошибки
}
//Закрытие клиента IrDA
if (irdaClient != null) {
try {
irdaClient.Close();
} catch {} //Поглотить любые возникающие ошибки
}
//Закрыть файл, в который осуществлялась запись
if (outputStream != null) {
try {
outputStream.Close();
} catch {} //Поглотить любые возникающие ошибки
}
//Закрыть прослушивающее устройство, если оно выполняется
if (m_irListener != null) {
//Установить первым, чтобы код, выполняющийся другим потоком,
//был отменен, если он установлен
m_wasListenerStopped = true;
try {
m_irListener.Stop();
} catch {} //Поглотить любые возникающие ошибки
m_irListener = null;
}
}
private void internal_WaitForIRFileDownload(
ref System.IO.Stream outputStream,
ref System.Net.Sockets.IrDAClient irdaClient,
ref System.IO.Stream irStreamIn) {
//---------------------------------------------------------
//Открыть входной файл для направления в него потока данных
//---------------------------------------------------------
outputStream = System.IO.File.Open(m_fileNameForDownload, System.IO.FileMode.Create);
//==========================================
//ОБНОВЛЕНИЕ СОСТОЯНИЯ
//==========================================
setStatus(ReceiveStatus.NotDone_WaitingForSender);
//---------------------------------
//Открыть прослушивающее устройство
//---------------------------------
try {
m_wasListenerStopped = false;
m_irListener = new System.Net.Sockets.IrDAListener(m_IrDAServiceName);
m_irListener.Start();
} catch (System.Exception eListener) {
m_errorDuringTransfer = "Error creating listener - " + eListener.Message;
goto exit_sub_with_error;
}
//Проверить, не поступила ли команда отменить выполнение
if (m_wasListenerStopped == true) {
goto exit_sub_with abort;
}
//------------------
//Принять соединение
//------------------
try {
//--------------------------------------------------------------------
//Выполнение будет приостановлено здесь до тех пор, пока устройство не
//начнет передавать информацию, или не будет остановлен объект
//прослушивания, выполняющийся в другом потоке)
//--------------------------------------------------------------------
irdaClient = m_irListener.AcceptIrDAClient();
} catch (System.Exception eClientAccept) {
//Если прослушивание остановлено другим потоком, инициировавшим отмену
//выполнения, будет сгенерировано исключение и управление будет
//передано сюда.
if (m_wasListenerStopped == true) {
goto exit_sub_with_abort;
}
//Если прослушивание не было прекращено,
//то произошло иное исключение. Обработать его.
m_errorDuringTransfer = "Error accepting connection - " + eClientAccept.Message;
goto exit sub_with error;
}
//B этом месте возможны два состояния:
//#1: Мы получили соединение от передающего устройства IR
//#2: IR-запрос был отменен (кто-то вызвал функцию STOP)
// (в этом случае приведенный ниже код сгенерирует исключение)
//Проверить, не было ли отменено выполнение
if (m_wasListenerStopped == true) {
goto exit_sub_with_abort;
}
//==========================================
//ОБНОВЛЕНИЕ СОСТОЯНИЯ
//==========================================
setStatus(ReceiveStatus.NotDone_Receiving);
//-------------------------
//Открыть принимающий поток
//-------------------------
try {
irStreamIn = irdaClient.GetStream();
} catch (System.Exception exGetInputStream) {
m_errorDuringTransfer = "Error getting input stream - " + exGetInputStream.Message;
goto exit_sub_with_error;
}
//Приготовиться к получению данных!
const int BUFFER_SIZE = 1024;
byte[] inBuffer = new byte[BUFFER_SIZE];
int bytesRead = 0;
do {
//Считать байты из порта IR
bytesRead = irStreamIn.Read(inBuffer, 0, BUFFER_SIZE);
//Записать байты в наш выходной поток
if (bytesRead > 0) {
outputStream.Write(inBuffer, 0, bytesRead);
}
} while (bytesRead > 0);
outputStream.Flush(); //Закончить запись любых выходных данных
//==========================================
//ОБНОВЛЕНИЕ СОСТОЯНИЯ: УСПЕШНО ВЫПОЛНЕНО
//==========================================
setStatus(ReceiveStatus.Done_Success);
return; //Ошибки отсутствуют
//==========================================
//ОШИБКА...
//==========================================
exit_sub_with_abort:
//ОБНОВЛЕНИЕ СОСТОЯНИЯ: Отменено (но не из-за ошибки)
setStatus(ReceiveStatus.Done_Aborted);
return;
exit_sub_with_error:
//ОБНОВЛЕНИЕ СОСТОЯНИЯ: ОШИБКА!!!!
setStatus(ReceiveStatus.Done_ErrorOccured);
}
} //конец класса
- Соединение равноправных узлов сети посредством IrDA
- Сокеты IrDA и .NET Compact Framework
- В настоящее время поддержка сокетов .NET для IrDA доступна лишь в .NET Compact Framework, тогда как в .NET Framework для настольных компьютеров она отсутствует
- В настоящее время код, использующий сокеты IrDA .NET Compact Framework, будет выполняться на таких физических устройствах, оборудованных аппаратурой IrDA, как Pocket PC и смартфоны, но не будет правильно выполняться на эмуляторах
- Листинг 15.3. Тестовый код, который необходимо поместить в класс формы для тестирования передачи и приема данных посредством механизма IrDA
- Листинг 15.4. Класс IrDAIrDAFileSend
- Листинг 15.5. Класс IrDAFileReceive
- Листинг 15.8. Вызов Web-служб путем неявной передачи параметров посредством cookie-файлов
- Листинг 15.10. Группирование запросов в одном вызове Web-службы
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Листинг 15.11. Код для загрузки файла с Web-сервера
- Листинг 3.1. Конфигурационный файл lilo.conf
- Листинг 3.2. Файл настройки программы inittab
- Листинг 3.3. Файл
- Листинг 3.4. Информация о конфигурации и состоянии сети
- Листинг 4.1. Файл
- Листинг 4.2. Содержимое конфигурационного файла
- Листинг 4.3. Информация о программе sudo
- Листинг 5.1. Файл конфигурации sshd